rest - 如果我的 API 已经按照 HAL 规范返回自链接,我应该为创建的资源使用位置标头吗?
问题描述
我正在关注一些博客和 SO 问题,他们建议Location
服务器返回一个带有201 created
响应的标头。Spring-data-rest
还会在标头中返回创建的资源位置Location
。
但是真的需要吗??
考虑这个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"
}
}
}
由于响应在self
和person
链接中具有创建资源的绝对位置,为什么Location
不再需要标头?
解决方案
如果您想符合HTTP 规范 (RFC 7231),您应该返回一个响应Location
头:201 Created
如果由于成功处理 POST 请求而在源服务器上创建了一个或多个资源,源服务器应该发送一个 201(已创建)响应,其中包含一个 Location 头字段,该字段为创建的主要资源提供标识符(第 7.1 节.2) 以及在引用新资源时描述请求状态的表示。
某些客户端实现将在此类前提下运行,如果您违反 HTTP 规范,它们可能无法与您的 API 正确交互。
此外,您必须区分一些特定于媒体类型的表示内容和一些一般的请求-响应元数据。标Location
头属于响应的元数据。不理解某种表示格式的客户端仍然知道服务器能够将内容存储在给定的 URI 上。
想一想任意客户端向服务器发送数据并且服务器以客户端不理解的表示格式(允许服务器)存储该数据的场景,客户端应该如何确定数据的位置或检索未来的数据?由于缺乏关于返回的表示格式的知识,并且通过从标头中省略此类信息,客户端是盲目的并且无法轻松地再次请求此数据,因此它无法处理响应。通过引入一个表示中立的提示,即每个表现良好的实现都应该遵循客户端,至少可以理解这一点。它可能仍然无法正确处理响应负载,但它知道数据在相应位置可用。
客户端和服务器应协商交换消息的实际媒体类型,以增加互操作性。因此,媒体类型描述了可能出现在交换的消息中的元素的语法和语义以及处理请求的规则集,即某些元素可能只出现在某些条件下。除了某些键值对包含在花括号式符号中之外,仅交换application/json
不会为客户提供有关如何处理数据的太多信息。虽然hal+json
为 URI 添加了语义,但它没有指定用于返回创建的资源的键,因为 HTTP 规范已经涵盖了这一点。
关于 REST,你可以以 Web 为例,介绍如何设计客户端和服务器之间的交互流程。这里的前提应该始终是服务器通过类似表单的表示格式和提供的链接来指导客户端下一步可以做什么。REST 架构的最终目标是将客户端与服务器解耦,从而允许后者在未来自由发展而不会破坏客户端。然而,这需要仔细设计,因为它很容易引入意外的耦合。
推荐阅读
- javascript - 我需要一个提示,只显示一次,保存一个用户名,然后在站点的其余部分使用它
- vbscript - 连接到 Microfocus ALM 的 VBS 脚本不起作用
- bash - 在 Bash 中比较多个变量是否相等
- c++ - 如何使用关键事件在 OpenGL 中转换对象?
- python-3.x - 如何使用 pytesseract 从工资单图像中提取指定文本
- r - 有没有办法将列作为时间、行作为日期的数据框转换为结合日期/时间的向量?
- heron - 如何访问 Heron 中的背压指标(Json 文件)
- mysql - MySQL:如何将表列聚合成列表并计数?
- git - Git不会合并(“已经是最新的”) - 如何在不重写历史的情况下解决这个问题?
- php - 将图像访问存储并显示到刀片视图中