【问题标题】:Mimetypes for a RESTful APIRESTful API 的 Mimetypes
【发布时间】:2010-12-18 22:36:43
【问题描述】:

http://kenai.com/projects/suncloudapis/pages/Home 的 Sun Cloud API 是一个很好的 RESTful API 示例。忠实于 RESTful 原则,当您 GET 资源时,您获得的只是该资源的表示形式。

响应中的 Content-Type 标头准确地告诉您该资源的类型,例如 application/vnd.com.sun.cloud.Snapshot+json。 Sun 已向 IANA 注册了这些 mimetype。

目前一般来说这有多实用?我见过的大多数 API 都使用了“application/json”的 Content-Type。这告诉您响应是 JSON,但仅此而已。你必须在 JSON 对象中有一些东西,比如“类型”属性,才能知道它是什么。

我正在设计一个 RESTful API(不会公开,因此我不会注册 mimetypes)。我一直在使用 RESTEasy,我发现即使我指定了一个完整的 mimetype,响应标头中的 Content-Type 也将完全是 Accept 请求标头指定的内容。如果请求默认要求“application/*+json”,则响应标头将包含“application/*+json”。我可以通过在响应发出之前更改标头来解决此问题,但我应该尝试这样做吗?还是应该像请求一样在响应中使用通配符?

或者我应该像大多数 API 那样提供“application/json”吗?

稍后添加的其他想法:

另一种表述问题的方式是:我应该使用 HTTP 作为协议,还是应该只使用 HTTP 作为传输机制来包装我自己的协议?

要使用 HTTP 作为协议,响应的实体主体包含请求对象的表示(或错误消息对象的表示),“Content-Type”标头包含对象的确切类型,以及“状态”标头包含成功或错误代码。

要将 HTTP 仅用作传输机制,“Status”标头始终设置为 200 OK,“Content-Type”是通用的,例如“application/json”,实体主体包含本身具有对象、对象类型、错误代码以及您想要的任何其他内容。如果你自己的协议是 RESTful 的,那么整个方案就是 RESTful。 (HTTP 是一种 RESTful 协议,但不是唯一可能的协议。)

您自己的协议对所有传输层都是不透明的。如果你使用 HTTP 作为协议,所有的传输层都会理解它,并且可能会做你不想要的事情;例如,浏览器会拦截“401 Unauthorized”响应并显示登录对话框,即使您想自己处理也是如此。

【问题讨论】:

    标签: json rest mime-types


    【解决方案1】:

    我使用我自己的 vnd.mycompany.mymediatype+xml 媒体类型来进行我的许多表示。在客户端上,我根据返回的表示的媒体类型分派到适当的控制器类。这确实允许服务器控制我的客户端应用程序的行为,以响应用户点击链接。

    就我个人而言,如果您希望支持 REST 客户端,我认为使用 application/xml 和 application/json 是您可以做出的最糟糕的选择之一。唯一的例外是客户端仅使用下载的代码(如 Javascript)来解释数据。

    【讨论】:

      【解决方案2】:

      或者我应该像大多数 API 那样提供“application/json”吗?

      我不这么认为。

      媒体类型是 RESTful Web 应用程序和使用它的客户端之间的唯一耦合点。您的媒体类型的文档就是您的 API 的文档。您的媒体类型是您的客户和您的应用程序之间的合同。消除特定的媒体类型,您就消除了使 REST 可行的重要元素。

      Sun 已向 IANA 注册了这些 mimetype。

      找不到any mention of that here。 AFAIK,不需要向 IANA 实际注册您的自定义媒体类型。约定似乎是使用 application/vnd.com.example.app.foo+json 的倒置域表示法,以防止命名空间冲突。如果并且当您的媒体类型变得稳定和公开时,这可能是一个好主意,但没有要求。不过,这可能是错误的。

      【讨论】:

      • 我在使用 Web 客户端时遇到的一个问题是浏览器拦截 HTTP 状态代码和标头。例如,如果您返回 401 Unauthorized,JavaScript 客户端在浏览器抓取它并建立自己的登录对话框之前不会看到它。从那时起,浏览器会在每个请求上放置自己的 Authorization 标头。 Mimetypes 通过 OK,但至少有一个状态码 (401) 有问题。
      【解决方案3】:

      通过指定完整的 mimetype,您会获得任何价值吗?如果 mimetype 是 application/json,你会对完整的 mimetype 做任何不同的事情吗?

      我的 2 美分 - 如果 API 不公开,那么我认为没有理由使用完整的 mimetype。 application/json 的 mimetype 应该绰绰有余。您已经知道响应返回的 json 类型。如果 API 最终公开,那么请担心一个完整的 mimetype……或者让人们弄清楚。

      【讨论】:

      • 正如 Rich 所提到的,mime 类型是您的合同。应用程序的整个语义值都包含在 mime 类型中。如果您只交付应用程序/json,则客户端可以从您的数据中获得非常少的价值,而不会引入带外耦合,这正是 REST 试图阻止的。
      猜你喜欢
      • 2013-06-04
      • 2012-05-20
      • 1970-01-01
      • 2018-07-17
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      相关资源
      最近更新 更多