RESTful API的MIME类型

5
Sun Cloud API在 http://kenai.com/projects/suncloudapis/pages/Home 上是遵循RESTful API的一个很好的例子。符合RESTful原则,当您获取资源时,您只会得到该资源的表示,不多也不少。
响应中的Content-Type头告诉您该资源的类型,例如application/vnd.com.sun.cloud.Snapshot+json。Sun已经向IANA注册了这些MIME类型。
总体上来说,这种方法目前有多实用?我看过的大多数API都使用“application/json”的Content-Type。这告诉您响应是JSON格式,但没有更多信息。您必须在JSON对象中添加“type”属性才能知道它是什么。
我正在设计RESTful API(不会公开发布,因此我不会注册MIME类型)。我一直在使用RESTEasy,并发现即使我指定了完整的MIME类型,响应头中的Content-Type也会与Accept请求头完全相同。如果请求默认要求“application/*+json”,则响应头将具有“application/*+json”。我可能可以在响应发送之前更改标头来解决此问题,但我应该尝试这样做吗?还是响应应该像请求一样具有通配符?
还是像大多数API一样提供“application/json”?
后续补充的想法:
另一种表述问题的方式是:我应该使用HTTP作为协议,还是仅使用HTTP作为传输机制来包装自己的协议?
要使用HTTP作为协议,响应的实体正文包含所请求对象的表示(或错误消息对象的表示),“Content-Type”标头包含对象的确切类型,“状态”标头包含成功或错误代码。
要将HTTP仅用作传输机制,则“状态”标头始终设置为200 OK,“Content-Type”为一些通用内容,例如“application/json”,实体正文包含某些自身具有对象、对象类型、错误代码和其他任何内容。如果您自己的协议是RESTful的,则整个方案都是RESTful的。(HTTP是RESTful协议,但不是唯一可能的协议。)
您自己的协议对所有传输层都是不透明的。如果您将HTTP用作协议,则所有传输层都将理解它并可能执行您不想要的操作;例如,浏览器将拦截“401未经授权”的响应并显示登录对话框,即使您想自己处理它也是如此。
3个回答

4
我在很多表现中使用自己的vnd.mycompany.mymediatype+xml媒体类型。客户端根据返回表现的媒体类型派发到适当的控制器类。这真的允许服务器控制客户端应用程序响应用户跟随链接的行为。
就个人而言,我认为如果你希望支持REST客户端,使用application/xml和application/json是最糟糕的选择之一。唯一的例外是当客户端仅使用下载的代码(像Javascript)来解释数据。

2
“或者我应该像大多数API一样提供'application/json'吗?”
我不这么认为。
媒体类型是你的RESTful web应用程序和使用它的客户端之间的唯一耦合点。你的媒体类型文档就是你的API文档。你的媒体类型是你的客户端和应用程序之间的契约。消除特定的媒体类型,就消除了使REST可行的一个重要元素。
“Sun已经在IANA注册了这些MIME类型。”
找不到这里有任何提及。据我所知,并没有要求实际上将你的自定义媒体类型注册到IANA。惯例似乎是使用倒置域表示法,如application/vnd.com.example.app.foo+json,以防止命名空间冲突。如果你的媒体类型变得稳定和公开,这可能是一个好主意,但并不是必须的。不过,我的理解也可能有误。

我在Web客户端遇到的一个问题是浏览器拦截HTTP状态码和头信息。例如,如果返回401未经授权状态码,JavaScript客户端在浏览器抓取并弹出自己的登录对话框之前无法看到它。从那时起,浏览器会在每个请求上放置自己的Authorization头信息。Mimetypes可以正常通过,但至少有一个状态码(401)存在问题。 - Mark Lutton

0

通过指定完整的MIME类型,您会得到任何价值吗?如果MIME类型是application/json,您会对完整的MIME类型进行不同的处理吗?

我个人认为,如果API不会公开,那么就没有必要使用完整的MIME类型。应用程序/ JSON MIME类型已经足够了。您已经知道响应返回的JSON类型。如果API最终变成公共的,然后再考虑使用完整的MIME类型...或者让使用者自行解决。


正如Rich所提到的,mime-type是您的合同。您的应用程序的整个语义价值都包含在mime-type中。如果您只提供application/json,则客户端在不引入带外耦合的情况下很难从数据中获取很少的价值,而这正是REST试图防止的。 - Darrel Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接