【问题标题】:Which URL should be used for GET, PUT, and DELETE of a child resource?哪个 URL 应该用于子资源的 GET、PUT 和 DELETE?
【发布时间】:2014-11-23 04:59:05
【问题描述】:

假设我有一个资源parent,它代表一组数据。类似这样的宁静 URL 结构应该非常简单:

  • GET /api/parents - 返回所有父母的集合
  • GET /api/parents/1 - 返回 id = 1 的父级
  • POST /api/parents - 向集合添加新的父项
  • PUT /api/parents/1 - 更新 id = 1 的父项中的数据
  • DELETE /api/parents/1 - 删除 id = 1 的父级

现在说每个parent 都由child 资源的集合组成。子资源 id 是否应该被视为具有全局或本地范围?我相信给出了以下 2 个 URL:

  • GET /api/parents/1/children - 返回父级 1 的子级集合
  • POST /api/parents/1/children - 将新孩子添加到父 1 的集合中

但是 GET、PUT 和 DELETE 呢?以下哪项是合适的?

  • GET、PUT 或 DELETE /api/parents/44/children/6
  • GET、PUT 或 DELETE /api/parents/children/6

这似乎归结为 child 资源 ID 的唯一性范围。 ID 是否仅在父聚合中唯一?还是在所有父母的所有孩子中都是独一无二的?一个比另一个更正确,还是取决于相关资源的 id 唯一性范围?

如果示例 1 比示例 2 更合适,并且 id = 44 的父代没有 id = 6 的子代(比如子代 id = 6 属于 id = 9 的父代),应该返回什么 HTTP 响应?

【问题讨论】:

    标签: http rest asp.net-web-api url-routing


    【解决方案1】:

    @danludwig

    我认为它实际上并不重要,因为 URI 只是资源标识符,所有这些用户友好的层次结构只对人类很重要......但无论哪种情况,我都会问关于这个“/api/parents”的问题/children/6",让我们分解一下:

    • GET to "/api/parents/children/6" 为我们提供子资源
    • GET 到“/api/parents/children”这里发生了什么? 404?
    • GET to "/api/parents" 给我们所有的父母
    • GET 到“/api”希望主页(或索引)文档,其中包含指向其他从属资源的链接。

    我认为在构建分层 URI 时这是一个很好的测试。只需确保每个段都绑定到特定资源并且不返回 404。

    【讨论】:

    • 关于通过 URL 倒退的好处,我应该想到这一点。你对问题的最后一段有答案吗?如果子 ID 不属于给定的父 ID,哪个 HTTP 响应代码更合适? GET、PUT和DELETE应该是404,还是根据HTTP请求方式不同的代码更合适?
    • @danludwig 404 是肯定的。如果资源不能被指定的 URI 识别,404 只是适当的响应。对于外部世界来说,你如何在你的实现中实现这些关系并不重要。但是当您使用 URI 标识资源时,这意味着整个 URI 标识的是实际资源,而不是它的段。 URI 是不透明的字符串,因此作为一个整体使用。
    【解决方案2】:

    ID 是否仅在父聚合中唯一?还是在所有父母的所有孩子中都是独一无二的?

    这取决于孩子是唯一一个父母的孩子的可能性。如果是这种情况,那么本地范围的 ID 是可能的。

    另一方面,如果一个子节点可以是多个父节点的子节点,则需要全局范围 ID。

    当然可以询问具有全局 ID 的子代是否只能存在于父代的“下方”,或者这样的子代是否可以通过不包含父代的 URL 来寻址。

    【讨论】:

      【解决方案3】:

      GET, PUT or DELETE /api/parents/44/children/6 URL 在我看来是因为它指示了父资源和子资源之间的关系。

      唯一的问题是您需要知道父 ID 才能使用子资源。

      另一种方法是一起删除 URL 的“父”部分:GET, PUT or DELETE /api/children/6,并在子资源中包含一个“链接”属性或元素,为其父资源提供 URL。

      <child>
         <id>6</id>
         <link rel="parent" href="/api/parents/1" />
         ...
      </child>
      

      【讨论】:

      • 至于您的替代答案,child 资源仅在parent 的上下文中才有意义。在 DDD 术语中,childparent 聚合所有,不应在其外部访问。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 2013-09-27
      • 2014-12-06
      • 1970-01-01
      相关资源
      最近更新 更多