首页 > 解决方案 > 如何在超媒体 api 的更新请求中引用资源?

问题描述

我对 REST API 如何工作以及如何通过超媒体链接资源进行了一些研究。大多数有关链接资源的示例都与服务器的响应有关。但是我想知道当某个资源应该更新时如何引用其他资源。

让我们以居住在特定位置的人的简单资源为例:

/api/persons/alice
{
  "name": "Alice",
  "location": {
    "id": 1,
    "links": {
      "self": "/api/locations/1"
    }
  }
}

现在我想将该位置更新为另一个现有位置。但是我该如何表示呢?我可以吗:

  1. 引用新位置的id
PUT /api/persons/alice
{
  "name": "Alice",
  "location": 2
}
  1. 引用新位置的 URI
PUT /api/persons/alice
{
  "name": "Alice",
  "location": "/api/locations/2"
}
  1. 还要别的吗?

标签: apiresthttprequesthypermedia

解决方案


HTTP PUT 具有远程创作语义 - 您应该将有效负载视为文档的新表示,由一些通用的 HTTP 感知文档编辑器操作。

GET /api/persons/alice HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json

{
  "name": "Alice",
  "location": {
    "id": 1,
    "links": {
      "self": "/api/locations/1"
    }
  }
}
PUT /api/persons/alice HTTP/1.1
Content-Type: application/json

{
  "name": "Alice",
  "location": {
    "id": 2,
    "links": {
      "self": "/api/locations/2"
    }
  }
}
200 OK

这里的假设是你的 API 的使用者熟悉这里的模式,并且理解语义,哪些字段是可选的,哪些是必需的,等等。

(让它在很长一段时间内工作意味着投入精力来设计你的模式,选择合理的默认值,等等)。

请仔细遵守PUT 规范的这一部分:

源服务器应该验证 PUT 表示是否与服务器对目标资源的任何约束一致,这些约束不能或不会被 PUT 更改......当 PUT 表示与目标资源不一致时,源服务器应该通过转换表示或更改资源配置使它们保持一致......

...

源服务器不得在对 PUT 的成功响应中发送验证器标头字段(第 7.2 节),例如 ETag 或 Last-Modified 字段,除非请求的表示数据在未对正文应用任何转换的情况下保存......

换句话说,服务器不需要“存储”所提供的新表示。


推荐阅读