如何解决用于验证答案的 rest API 中的正确路径是什么?
出于教育目的,我正在 MERN 堆栈中构建一个网站。它有一个调查问卷,其中包含针对一个特定主题的 40 个“是或否”问题(可以是对也可以是错的陈述)。可以有很多主题,但所有主题的陈述总是相同的。
在用户完成回答后,答案应该被发布到(或从?)一个休息 API。
后端只是从数据库中获取正确的答案,然后根据这些答案验证用户的答案并给出结果。
后端的模型只是简单的文档,每个文档都包含 subject id
和 40 个布尔值 as1
到 as40
。
(nosql 新手,所以我可能已经完全删除了我的模型,在这种情况下,我很乐意接受纠正!)
我想我要使用这样的 POST 正文:
{
"answers": {
"uas1": true,"uas2": false,...
"uas39": true,"uas40": false
}
}
...但是路径应该是什么样的?
/statements/:id/answer
?
解决方法
调用此休息服务的正确方法是什么?
您需要解决的主要问题是了解客户端是获取资源(有效的只读操作)还是修改资源。获取资源可能意味着从缓存中获取资源,而不是让请求一直传递到您的服务器。
后端只是从数据库中获取正确的答案,然后根据这些答案验证用户的答案并给出结果。
这听起来很像有效只读的情况:给定答案列表,找到匹配的答案文档。因此,对于这种资源模型,通常的答案是使用 GET。
在网络上,这可能看起来像一个包含 40 个不同问题的输入控件的大表单。用户将做出他们的选择,然后点击提交按钮。浏览器将使用输入来计算查询字符串,并执行 HTTP GET 请求,并将所有用户输入编码到查询部分(根据表单本身的元数据。
?a1=Y&a2=N&a3=T...&a40=Y
使用 HTML 表单,我们可以为我们想要的路径使用任何拼写,同样我们可以为查询部分中的键使用任何我们想要的拼写,因为该信息成为表单元数据的一部分:浏览器只需查看表单定义,它描述了如何创建有效的请求 URI(它是 HTML 表单处理标准的一部分)。
对于主题 id 之类的东西,您可以选择将该信息编码到路径中(通过将该信息作为表单操作的一部分)或编码到查询部分(作为表单输入 - 可能是“隐藏”)。
路径应该是什么样的?
您喜欢的任何东西 - REST 不关心您为资源标识符使用什么拼写约定。
GET /83eeecdd-a680-475f-913b-07aa0239cec0?a1=Y&a2=N&a3=T...&a40=Y
...很好。不过,您可能想要一些对人类更好的东西 - 操作员阅读日志、用户扫描浏览器历史记录、试图为其他开发人员记录资源模型的作者等。
GET /subject/:subject_id/answers?a1=Y&a2=N&a3=T...&a40=Y
也不错。
我想我要使用这样的 POST 正文:
根据您的描述,这不是我的首选。
像这样的请求
POST /statements/:id/answer
Content-Type: application/json
{...}
从通用组件的角度来看,限制很少;通用组件不能假设 POST 是有效只读的。这意味着我们无法从缓存中提取答案。事实上,情况恰恰相反:成功的 POST 请求将导致通用缓存invalidate 以前使用相同的有效 uri 存储的响应。
通用组件甚至不能假设 POST 请求具有幂等语义,因此如果响应丢失,HTTP 应用程序无法通过重新发送请求来自动帮助我们。
如果有效的只读语义不是您想要的,那么 it is okay to use POST。使用 HTML 表单,那将是我们唯一真正的选择。
但是如果您可以设计您的资源模型,使得每组提交的答案都是它自己的资源,那就更好了。您可能会这样想:用户得到一个独特的问卷,其中所有的答案都是空白的。他们填写自己的答案,然后返回该独特问卷的新表示。
将您的 API 实现为对文档的编辑允许您使用 PUT; PUT 具有幂等语义,这意味着通用组件可以在响应在不可靠网络上丢失时自动提供帮助。
PUT /statements/123/answers/Bob
Content-Type: application/json
{
"answers": {
"uas1": true,"uas2": false,...
"uas39": true,"uas40": false
}
}
这里,我们有一个特定于 Bob 答案的资源,请求描述了对该资源的编辑。
从技术上讲,您可以让每个人编辑相同的资源
PUT /statements/123/answers
...
这不是很好,但您可以获得很多好处。每个成功提交的请求都会使目标资源失效,但您可能不太关心。
我不会称这种方法符合 REST,但它可能算作 REST-close-enough-that-you-get-away-with-it。
,您应该设计 API 端点(或“路径”),使它们真正具有描述性,并且针对每个场景。所以考虑到这一点,其中一个端点可能看起来像:
/subject/:subject_id/answers
然后在您的前端,您将 POST 请求发送到例如
http://127.0.0.1/3000/subject/23/answers
请求正文如下所示:
{
"answers": {
"uas1": true,"uas40": false
}
}
这个端点本质上的作用是将 ID 为 23 的主题的所有 40 个布尔答案发送到您的 Express.js 服务器。
然后您的服务器将解析请求并从您的 req.body 中获取答案,然后根据您的 MongoDB 数据库进行检查。该检查的结果然后可以在如下响应中发回:
res.status(200).send(`For subject ${subject_name},you scored ${correct_answers}/40`)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。