为什么在 API 场景中 HTTP 内容协商优于显式参数?

Why would HTTP content negotiation be preferred to explicit parameters in an API scenario?

HTTP content negotiation can be used to make client and server agree on a data format and language. Maybe you're interested in my previous question ()但没必要看

在开发 HTTP-based API 时,这个概念真的有意义吗?(API 是一个未使用的 Web 服务最终用户。它以编程方式专门调用。)

内容协商的替代方法是 "regular" 参数(例如 http://example.org/myService?someParam=1234&lang=en&format=xml)。

大多数 client-side 框架使得调用 Web 服务和发送参数变得非常容易。配置特殊的 HTTP headers 通常要困难得多。使用HTTP内容协商似乎工作量更大

同时也没有必要协商。客户端将以知道可用的格式和语言的方式进行编程。因此,它只会在这方面进行有效调用并得到它想要的东西。

如果服务器想要拒绝呼叫,它可以发送 application-level 错误而不是 HTTP 错误。 Application-level 根据我的经验,错误更容易处理。无论如何,您都需要该代码。您不一定需要解释 HTTP 错误。您可以将所有这些都视为一般故障。

内容协商似乎很符合 REST 哲学,但我对具体的成本和收益更感兴趣。

HTTP 内容协商在哪些方面优于仅添加 API 参数?

我没有使用过许多吹捧能够与任何 RESTful API out-of-the-box 一起工作的框架。主要是因为在没有非常广泛的配置功能的情况下,与任何可能的 RESTful 实现进行通信是不可行的,而我所看到的配置则没有。然而,这是框架的错误,而不是 API.

与 request/response headers 合作对于与 well-designed RESTful API 的任何人进行交流至关重要。 Headers 可用于发送访问令牌和消息 body 签名等信息,以及接收 collection 大小和分页详细信息等信息。为什么不使用一个已经存在的系统来协商内容格式呢?使用现有 HTTP 规范的全部范围正是 REST 的目的。

关于 HTTP 错误...为什么要对它们一视同仁? 404 的处理方式应与 400 的处理方式大不相同,400 的处理方式应与 409 大不相同。要么我误解了你,要么我认为你错过了 REST 的一些关键方面。

Does this concept really make sense when developing an HTTP-based API? (An API is a web service that is not used by end users. It's called exclusively in a programmatic way.)

是的,现在仍然如此。

The client will be programmed in such a way that it knows what formats and languages are available.

这听起来像是您将客户端耦合到特定的 API,这有点忽略了重点。客户端应该完全理解那些它自己理解的media-types,但是为什么它应该知道什么是可用的?

菲尔丁自己写道:

REST is intended for long-lived network-based applications that span multiple organizations.

现在,特别是关于 谈判 ,菲尔丁有一个有趣的观察,在大多数情况下,你会想要 each negotiated resource to have it's own identifier.

因此 http://example.org/myService?someParam=1234 与适当的 headers 将 return 表示 http://example.org/myService?someParam=1234&lang=en&format=xml。这可能是通过重定向(这似乎是 Fielding 在 2006 年认为最合适的机制),或者它可能只是立即 return 协商表示,metadata 提供 [=47] 的标识符=]ed 代表

请注意,后一个请求仍然是无状态的——如果您协商特定资源的方式,或者您立即想要的资源,服务器不应该有任何不同的响应。例如,您可能最终与一台服务器进行协商,并 re-directed 在完全不同的主机上成为您想要的表示。

这意味着服务器无法真正区分协商的客户端和不协商的客户端。您可以简单地将协商资源的标识符直接连接到您的客户端,它将“起作用”。

In what way is HTTP content negotiation superior to just adding an API parameter?

标准化。通过内容协商,我的 generic 客户不需要了解您的 api 使用的拼写约定。中间组件(例如:缓存)也不需要知道您的拼写约定。

Does this concept really make sense when developing an HTTP-based API? (An API is a web service that is not used by end users. It's called exclusively in a programmatic way.)

回到这一点:REST 是一种 collection 架构约束,选择用于引发特定属性。换句话说,我们正在权衡取舍。如果长期客户的优势在您的环境中没有价值,那么支持该用例的架构限制将不会发挥其全部作用。