虽然 accept-language(如建议的链接 Kit 所发布的那样)可能正在尝试,但它仅支持由 IANA 维护的 registered languages,网络的标准化团体,但不支持某些开箱即用的通用配置选项。它可能会尝试默认为miles,即Accept-Language: us,并在其他地方使用km,如果美国科学家想使用km而不是miles,您的应用程序可能会遇到某些问题。但如果情况并非如此,那么这显然是您可以考虑的一个选择。关于自定义 HTTP 标头,我不建议使用这些,因为自定义 HTTP 标头的问题通常是任意通用 HTTP 客户端不支持这些,这在某种程度上与应该使用 REST 架构的想法相矛盾。
让我们将您的问题转移到 Web 域,看看我们通常如何在那里解决该任务。由于 REST 基本上只是我们人类与 Web 交互的常见方式的一种通用方法,因此 Web 上使用的任何概念也适用于 REST 架构。因此,将整个交互流程设计为就像您的应用程序在典型网页上进行交互一样只是常见做法(或至少应该如此)。
在 Web 上,所谓的Web form 用于“教”Web 客户端(也称为浏览器)服务器期望作为输入的数据。它不仅教客户端关于服务器期望或支持特定资源的相应属性,还教客户端使用哪种 HTTP 方法,关于将请求发送到的目标 URI 以及关于要使用的媒体类型,这通常是隐含的只是作为application/x-www-form-urlencoded 给出,但也可能是multipart/form-data。
表单和链接的使用属于 HATEOAS 约束,其中这些 concpets 允许客户完成他们的任务,即在网上商店购买商品或管理系统中的用户,而无需咨询外部文档。这里的应用程序基本上只是使用内置的超媒体功能来完成他们的任务。客户端通常遵循某种predefined processes,其中服务器指示客户端他们需要做什么才能将商品添加到购物车或如何添加或编辑用户,同时仍然只是在通用 HTML 文档上进行操作本身并不适合手头的相应任务。这种方法允许 Web 客户端基本上呈现各种页面,并且用户可以与这些通用页面进行交互。如果该页面表示中的某些内容发生更改,您的浏览器将自动适应并在下一次请求时呈现新版本。因此,系统能够随着时间的推移而发展并轻松适应变化。这可能是任何人基本上都想使用 REST 架构的核心原因之一。
那么,回到主题。在 Web 上,服务器会向客户端宣传它支持具有上述形式的各种本地化信息。可能会向用户呈现一个选项或下拉选项,其中她/他可以选择适当的选项。用户通常根本不关心这个输入是如何传输到服务器的,或者根本不关心服务器的内部结构。她/他所关心的是在提交请求后数据将可用(在添加或更新资源的情况下)。这也适用于 REST 架构中的应用程序。
您可能会在这里看到一个模式。 REST 和可浏览的 Web 基本上是一回事。后者虽然侧重于人机交互,而入门者应该允许应用程序“网上冲浪”和follow allong processes outlined by the server(半)自动。因此,现在应该很清楚,适用于可浏览 Web 的相同概念也适用于 REST 和该 REST 架构中的应用程序。
我喜欢第一个选项,因为它不会改变 api 合约
客户端不应绑定到特定的 API,因为这会产生耦合,REST 会不惜一切代价避免这种情况。除了直接绑定到 API,Web 以及 REST 也应该使用contracts build on hyper media types,它定义了所交换消息的可接受语法和语义。通过将合约从 API 本身抽象为媒体类型,客户端可以同时支持各种合约。媒体类型的泛化还允许即用相同的媒体类型表达各种不同的事物,从而增加重用的可能性,从而更好地支持应用层的集成。
支持各种媒体类型类似于说不同的语言。通过能够说各种语言,您只会增加您能够开箱即用地与其他人(服务)交流的可能性,而无需之前学习这些语言。客户端可以通过Accept 标头告诉服务器它能够“说”哪些媒体类型((也称为进程),服务器将响应其中任何一个或响应406 Not Acceptable。该错误响应是,正如 Jim Webber 所说,coordination data 始终告诉您是否一切顺利,或者在出现故障时会向您反馈问题所在。
因此,为了保持面向未来,我建议围绕支持表单的超文本媒体类型(即 HTML 表单、applicaiton/hal-forms+json 或 application/ion+json)设计配置。如果将来您需要添加更多配置选项,添加这些只是一项微不足道的任务。该配置是否公开为您只是链接到的自己的资源,作为资源中的嵌入部分或根本不返回给客户端也是您可以选择的。如果相同的配置可能被多个资源使用,那么将其公开为自己的资源,然后创建从资源到该配置的引用是有益的,但如上所述,这些是您必须做出的设计决策。