当前位置: 首页 > 知识库问答 >
问题:

在RESTful API中处理嵌套资源的正确方法是什么?

公羊涛
2023-03-14

考虑到我正在使用以下RESTful APIendpoint:

  • /users/:显示所有用户
  • /users/$user_id/:显示特定用户
  • /users/$user_id/posts/:按用户显示所有帖子
  • /users/$user_id/posts/$post_id/:按用户显示特定帖子

这个数据模型中的约束:一篇文章总是有一个用户。

“处理嵌套资源”是指处理CRUD操作。

我应该在 /users/$user_id/posts/ 终结点上实现 CRUD 操作(POST、PUT、PATCH、DELETE),还是应该创建另一个终结点 /posts/ 并在那里处理 CRUD 操作,同时保持第一个终结点为只读?

抱歉,如果这个问题已经以SO的另一种形式存在。:-)RESTful API周围有太多的“FUD”。

提前感谢任何提示/澄清!

亲切的问候,K。

共有2个答案

吕冠宇
2023-03-14

在Roy Fielding对REST的澄清之后,我建议您不要担心URL的设计:

REST API 不得定义固定的资源名称或层次结构(客户端和服务器的明显耦合)。服务器必须能够自由地控制自己的命名空间。相反,允许服务器通过在媒体类型和链接关系中定义这些指令来指示客户端如何构造适当的 URI,例如在 HTML 表单和 URI 模板中完成的 URI。[此处的失败意味着客户端由于带外信息而采用资源结构,例如特定于域的标准,该标准是面向数据的,相当于RPC的功能耦合]。

测试API的RESTfull的一个好方法是用统一ID替换所有精心构建的URI,并查看客户端是否可以使用这些信息。如果不是的话,你依赖带外信息,可以改善你的Rest。但是,类似于第n级数据库规范化,您可能希望少一点“正确性”,以便使所有参与者的工作更容易。需要多少正确性取决于您的域的不稳定性,以及您是否希望API用户数量更少或更多。

如果您想在URI中编码带外信息,我会尽量限制所需的信息。由于/user/$user_id/post/$post_id/需要用户知道三件事(URL设计、User ID、Post ID),似乎有一些替代方案可以让用户更加无知;-)

  • /posts/$post_id:更好,因为您的用户只需要一个 id 和资源类型来构造 URI
  • /$resource_id:最好,但需要全局唯一 ID
汪胤
2023-03-14

您应该在现有的 /posts/ 和 /posts/$post_id/ 终结点上实现这些操作。很少有充分的理由创建表示相同资源的多个终结点。为什么要让他们知道他们只能在/users/$user_id/posts/$post_id/上GET,但必须转到/posts/$post_id/才能删除?

有时,人们将其实现为

/users/: show all users
/users/$user_id/: show specific user
/users/$user_id/posts/: show all posts by user  -- GET only

/posts/: show all posts                         -- All operations
/posts/$post_id/: show specific post by user    -- All operations

他们使用/user/$user_id/post/作为对用户帖子的非规范引用。虽然我不能称之为错误,但最好坚持每个资源使用一个endpoint。过滤器参数没那么难。

 类似资料:
  • 问题内容: 嵌套的RAL居? 假设我正在尝试做Spark中的“嵌套循环”。就像普通语言一样,假设我在内部循环中有一个例程,该例程以Pi Average Spark示例 的方式估算Pi(请参见估算Pi) 我可以在Spark中嵌套并行化调用吗?我正在尝试,但还没有解决。乐于张贴错误和代码,但我想我要问一个更概念性的问题,即这是否是Spark中的正确方法。 我已经可以并行化一个Spark实例/ Pi估计

  • 问题内容: 我一直在使用spring-webflux进行一些研究,我想了解使用路由器功能处理错误的正确方法。 我创建了一个小项目来测试几个场景,并且我希望获得有关它的反馈,并查看其他人在做什么。 到目前为止,我在做什么。 提供以下路由功能: 我已经在我的处理程序上执行了 它们是我的错误处理程序: 这是完整的示例存储库: https://github.com/LearningByExample/re

  • 问题内容: 在PHP系统中,我有一个常见的MVC情况:从包含的数据中接收请求。现在,我有三种方法来处理数据: a)仅调用和处理数据。 b)在变换的数据转换成变量,并将它们传递到。 c)将数据转换为的域对象,并将该对象仅传递给。 目前,我正在使用选项A,但是我认为这是错误的,因此我正在考虑使用选项C。 因此,根据MVC,处理数据的正确方法是什么? 编辑 目前,我没有使用任何MVC框架。 编辑2 通常

  • 问题内容: 我使用10gen的本机node.js驱动器将mongodb(2.2.2)与node.js一起使用。 起初一切顺利。但是当涉及到并发基准测试部分时,会发生很多错误。频繁进行1000次并发连接/关闭可能会导致mongodb拒绝任何进一步的请求,并出现以下错误: 另外,如果许多客户端在没有显式关闭的情况下关闭,则mongodb将花费几分钟的时间来检测并关闭它们。这也将导致类似的连接问题。(使

  • 我试试看。js与mongodb(2.2.2)一起使用本机节点。js drive by 10gen。 起初一切都很顺利。但在并发基准测试部分,出现了很多错误。频繁连接/关闭1000次并发可能会导致mongodb拒绝任何进一步的请求,错误如下: 此外,如果很多客户端在没有显式关闭的情况下关闭,mongodb需要几分钟来检测并关闭它们。这也会导致类似的连接问题。(使用/var/log/mongodb/m

  • 在学习Java 8 streams和lambas时,我尝试用streams替换以下嵌套for循环: 循环迭代“ProvidedService”对象的列表,对于每个对象,循环遍历“Desk”对象的列表属性,并将“Id”字段提取到列表中。 我使用streams生成了以下代码: 这是正确/最佳的方法吗?或者有没有一种方法可以在没有第二个嵌套流的情况下实现这一点?