如果我的 API 已经根据 HAL 规范返回自身 link,我是否应该为创建的资源使用 Location Header?

Should I use Location Header for the created resource if my API is already returning the self link as per HAL specification?

我正在关注一些博客和 SO 问题,他们建议服务器返回一个 Location header 201 created 响应。 Spring-data-rest 也 returns 在 Location header 中创建的资源位置。

但是真的需要吗??

考虑这个 POST 请求: curl -d '{..data}' -H "Content-Type: application/json" -X POST http://localhost:3000/persons
回应:

{
  "name": "hero",
  "_links": {
    "self": {
      "href": "http://localhost:8081/persons/1"
    },
    "person": {
      "href": "http://localhost:8081/persons/1"
    }
  }
}

既然响应在 selfperson link 中具有创建资源的绝对位置,为什么还需要 Location header?

返回新创建的数据object只是一个方便的功能。 通常你得到的只是一个 201 响应,其中包含 Location header 而根本没有 BODY。

Spring 如果您设置以下应用程序属性之一或请求具有 Accept header,则数据仅 returns body。

spring.data.rest.return-body-on-create= # Whether to return a response body after creating an entity.
spring.data.rest.return-body-on-update= # Whether to return a response body after updating an entity.

如果您想遵守 the HTTP spec (RFC 7231),您应该 return Location header 以获得 201 Created 响应:

If one or more resources has been created on the origin server as a result of successfully processing a POST request, the origin server SHOULD send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created (Section 7.1.2) and a representation that describes the status of the request while referring to the new resource(s).

某些客户端实现将在此类前提下运行,如果您违反 HTTP 规范,它们可能无法与您的 API.

正常交互

此外,您必须区分一些 media-type 特定表示内容和一些一般 request-response 元数据。 Location header 属于响应的 meta-data。不理解某种表示格式的客户端仍然知道服务器能够将内容存储在给定的 URI 中。

考虑这样一个场景:任意客户端向服务器发送数据,服务器以客户端不理解的表示格式存储该数据(服务器允许),客户端应该如何确定数据的位置数据或将来检索数据?由于缺乏对表示格式 returned 的了解,并且从 headers 中省略此类信息,客户端是盲目的,因此无法处理响应,并且无法轻松地再次请求此数据.通过引入一个 representation-neutral 提示,即每个 well-behaved 实现都应该遵循,客户至少可以理解这一点。它可能仍然无法正确处理响应负载,但它知道相应位置的数据可用。

客户端和服务器应就实际 media-type 交换消息进行协商,以提高互操作性。因此,media-type 描述了可能出现在交换的消息中的元素的语法和语义以及处理请求的规则集,即某些元素可能只出现在某些条件下。除了某些 key-value 对包含在 curly-brace 式符号中之外,仅交换 application/json 并不能为客户提供太多关于如何处理数据的信息。虽然 hal+json 为 URI 添加了语义,但它没有指定用于 return 创建的资源的密钥,因为 HTTP 规范已经涵盖了这一点。

关于REST,你可以以Web为例,来设计客户端和服务端的交互流程。这里的前提应该始终是服务器通过 form-like 表示格式和提供的链接教导客户端下一步可以做什么。 REST 架构的最终目标是将客户端与服务器解耦,允许服务器在未来自由发展而不会破坏客户端。然而,这需要仔细设计,因为它很容易引入意外耦合。