【问题标题】:How to design a simple CRUD REST API如何设计一个简单的 CRUD REST API
【发布时间】:2013-05-08 10:59:44
【问题描述】:

我正在设计一个简单的 CRUD REST API。这是我的第一次,所以我想就我的设计是否有意义得到一些反馈。

我正在使用 HTTP 方法:GET、POST、DELETE 和 UPDATE。 API 将使用和获取 JSON 格式的数据。示例 URL 将如下所示:

GET (list): curl http://<domain>/myapp/rest/v1/colors
POST: curl -XPOST http://<domain>/myapp/rest/v1/colors -d '{
       "name": "red",
       "shade": "light"
      }'
GET (single item): curl http://<domain>/myapp/rest/v1/colors/2
DELETE: curl -XDELETE http://<domain>/myapp/rest/v1/colors/2
etc...

问题

在 POST 请求之后,将在数据库中创建一条记录。那么,POST请求是否应该返回新创建记录的ID呢?这样那个ID就可以在UPDATE, DELETE and GET (single item)中使用了?

【问题讨论】:

  • 这取决于你如何设计你的休息服务。是的,一个 POST 请求可以接收响应体。
  • 谢谢,是的,我知道 POST 可以接收正文。但是我可以在处理请求后发送响应,例如,新创建的记录的 ID 为 659
  • 是的,如果这些 ID 与您的数据库同步,您可以使用这些 ID。
  • 一个务实的答案是:是的,返回新创建的项目的 ID(自动递增的主键?)。这是否符合 REST,因此 HTTP 标准的规定是有争议的。

标签: java api rest grails


【解决方案1】:

HTTP specification 为 POST 定义了以下内容:

如果在源服务器上创建了资源,则响应应该是 201(已创建)并包含描述请求状态并引用新资源的实体和 Location 标头(参见第 14.30 节)。

所以这基本上意味着:

  • 您应该返回 201 Created 作为状态码
  • 您应该返回一个Location 标头,指向新创建资源的URI
  • 您可以选择在 POST 响应正文中包含资源的表示,以使客户端不必针对从 Location 标头获得的值发出另一个 GET 请求。

【讨论】:

  • 不错。所以第三个项目符号意味着我可以简单地返回新创建的 ID
  • 没有。首先,URI ID(因此得名)。其次,我写了“资源的表示”,这意味着如果您点击 Location 标头中的链接,您会得到基本相同的内容,阅读:您最初在您的案例中发送的 JSON。
【解决方案2】:

POST 应该返回一个重定向到单个项目的新 url。

您可能希望取消 url 的版本标识符。

而是以优雅地处理各种版本的方式设计您的表示和客户端。例如,客户端不应依赖于特定格式,而应仅依赖于它实际需要的属性。

您的描述中缺少的是 HATEOAS 原则,即客户端不应对任何 URL 进行硬编码,而是在其他实体的表示中查找 URL 以进行进一步操作。由于您没有为 URL 返回的结果显示示例文档,因此我们无法判断您是否以一种很好的方式这样做。

查看this presentation,它解释了主题并提到了一些有助于实现它的 Spring 库。

【讨论】:

  • 谢谢,我不知道 HATEOAS 原则。顺便说一句,即使标签丢失,我也在使用 grails 来完成此操作。我会添加标签。因此,帖子不应仅返回 ID,而应返回单个项目的完整 URL,即 'http:///myapp/rest/v1/colors/2'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 2021-08-06
  • 1970-01-01
  • 2019-03-09
  • 2014-10-19
相关资源
最近更新 更多