【问题标题】:REST URL structure adviceREST URL 结构建议
【发布时间】:2011-10-29 20:26:01
【问题描述】:

我正在尝试为我正在处理的网站的愿望清单部分确定一个宁静的 url 结构。这是一个非常简单的模型,一个用户可以有许多愿望清单,每个愿望清单可以包含许多产品。

目前我有明显的 CRUD URL 来操纵愿望清单本身:

GET account/wishlists.json
GET account/wishlists/{id}.json
POST account/wishlists.json?name=My%20Wishlist
POST account/wishlists/{id}.json?name=My%20New%20Name
DELETE account/wishlists/{id}.json

但是,我认为我不知道如何构建将产品添加/删除到愿望清单的 URL :(

这是我目前的选择:

1) 将产品添加为 URL 的一部分并使用 HTTP 动词来定义我的操作

POST account/wishlist/{id}/product/{product_id}.json
DELETE account/wishlist/{id}/product/{product_id}.json

2) 将操作作为 URL 的一部分,将产品 ID 作为有效负载的一部分

POST account/wishlist/{id}/add.json?product_id={product_id}
POST account/wishlist/{id}/remove.json?product_id={product_id}

(1) 很干净,据我所知,它非常 RESTful,但不允许轻松添加多个产品等操作。

我也有点担心使用 DELETE 动词 - 我没有删除产品或愿望清单,我只是从另一个中删除一个。

(2) 更明确,但与 REST 不同——我不仅仅指 url 中的资源,我指的是对该资源的操作:(

任何关于上述哪个更正确的建议都会非常有帮助! (如果有比我更好的第三种选择,请随时纠正我!)

【问题讨论】:

  • 懒得给出完整的答案,但要明确一点,选项二决不能被视为 REST,因为您在 URI 中有一个操作。

标签: http url rest


【解决方案1】:

(1) 是 REST 唯一有效的方法,将 HTTP 动词用于操作。

(2) 将方法名称编码为 URI,这更像 RPC,当然不是 RESTful。

关于你对第一种方法的缺点:

  • DELETE 动词很好,因为您的资源是愿望清单中的项目,而不是项目本身。
  • 您可以支持批量请求。例如,您可能希望允许 POST 将项目列表添加到愿望清单资源中,从而导致多次添加。

PS:优先使用 HTTP 内容协商(Accept 和 Content-Type 标头)而不是 URI 中编码的表示格式。

【讨论】:

  • 关于内容协商等,我预计允许用户发送任何内容,无论是标题还是 URL 扩展;在我的示例中编写 .json 是最简单的;)
  • 好的,只是偶然发现了你的例子并想提一下:-)
  • @deanWombourne @PartlyCloudy 我认为.format 有权明确要求以特定格式返回,因为在接受标头的情况下,服务器决定最终发送哪种格式。但是,如果没有可用的 JSON 响应(在您的示例中)或用户要求提供不可提供的格式(当您只有 json 时为 .xml),您必须返回 404 Not Found 标头,而不是提供替代表示。
  • @SamuelHerzog 没有强制服务器注意 URI 中的格式。我认为唯一一次将格式包含在 URI 中是当人们将 URI 输入 Web 浏览器时,因为它(目前)手动设置标题太乏味了。通过标头进行的内容协商应该是默认设置。如果无法处理这种格式,服务器仍然可以返回适当的响应。
  • @thecoshman 在构建 API 时,您的主要兴趣应该是您的用户/消费者——这就是我们首先需要 REST 的原因。我认为,如果您让消费者可以要求明确的格式(允许类似文件系统的 URI),您需要正确处理内容:如果消费者要求 XML 文件,您需要提供 XML 或告诉用户它不可用。如果您的客户能够进行内容协商,他就有办法对文件格式的变化做出反应。如果你公开一个带有“文件结尾”的 API,你就不能再依赖它了,需要对 404 状态码做出反应。
【解决方案2】:

我认为您的第一个选项更符合 REST 理念。如果要操作多个产品,可以将 id 作为列表传递到正文中,而不是使用查询参数。

至于删除部分,鉴于您要删除愿望清单的子资源,我认为意图很明确(即删除愿望清单与产品的连接)。如果您想全局删除产品,则 URL 应类似于

DELETE /products/{id}

【讨论】:

    【解决方案3】:

    正如其他回复所指出的,第一个选项显然是 RESTful 方法。从愿望清单中删除产品的方法看起来不错 - 毕竟您将在 product/{product_id} 上执行 DELETE 以删除产品本身。

    对于添加产品,您可能希望考虑使用 POSTaccount/wishlist/{id}/product/,其正文可以包含产品 ID 列表。

    【讨论】:

      【解决方案4】:

      Here's a nice article 关于如何考虑 REST URL

      【讨论】:

        猜你喜欢
        • 2011-06-03
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 2013-06-12
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多