从JSON API返回HTML是否可以?


25

在我当前的项目中,我负责服务的实现,该服务涉及使用新创建的RESTful API,这些文档记录为仅支持JSON。

客户端始终使用“ application / json”的接受标头和“ application / json”的内容类型发出请求。但是,某些端点会发送带有HTML内容类型的响应,甚至是HTML正文。对我来说,这显然是错误的方法,永远无法辩解。

在整个项目中,相同的做法已应用于两个不同的供应商和两个不同的服务。我发现自己必须证明为什么需要更改服务。供应商表示,客户端应对此进行处理,甚至我选择的REST库也受到了质疑(RestEasy),因为默认情况下它不应对此问题。

这是一个主要的挫败点。我找不到很多引用来支持我的论点,我认为这是因为要点很明显,所以没有意义。

问题是,我缺少什么吗?我对此很腐吗?在这种情况下,可以使用不具有application / json内容类型的JSON API吗?参考将不胜感激。您如何从商业角度解决这种情况?


1
上下文类型是指内容类型HTTP标头吗?
Marjan Venema

是的,我指的是HTTP内容类型标头。编辑。
phillip.darley

好吧,至少当它们是HTML REST API时,他们一定不能将其称为“ JSON REST API”。
Bergi

Answers:


28

当您发送accept请求特定媒体类型的标头时,服务器不应发回其他任何东西,并且最肯定的是不会发送200 OK状态代码

来自Restpatterns.org

如果不存在“接受”标头字段,则假定客户端接受所有媒体类型。如果存在一个Accept头字段,并且如果服务器不能根据组合的Accept字段值发送可接受的响应,则服务器应该发送406(不可接受)响应。

(强调我的)

Restpatterns.org从实际的HTTP标准获取此信息:标头字段定义-接受

简而言之:您不是在学究。如果服务在接受标头专门告诉它们返回application/json且没有其他内容时返回HTML,则它们不遵循HTTP标准。


1
+1。我同意这个答案,但是遗憾的should是在HTTP规范中反复使用了这个词。我们必须开始在线请愿,以将这些单词更改为must
Reactgular

3
@MarjanVenema“应该”是正确的,因为在同一RFC中的第10节中有一条注释:“根据请求中发送的接受标头,允许HTTP / 1.1服务器返回不可接受的响应。在某些情况下,甚至比发送406响应更好。”
imel96

1
如果客户端请求的资源实际上没有 JSON表示形式,那么无论他们想要多少JSON,他们最好还是收到其他确定的信息;您不能保证会得到406。重要的是,服务器应描述响应的内容类型实际上是什么。
Donal Fellows

6
@DonalFellows:不,最好知道实际情况。服务器不仅应该发回它认为合适的任何内容,还应该发送标准中规定的406不可接受的响应。请记住,当客户端专门请求一种媒体类型并且未指定任何后备时,它可能无法处理任何其他媒体类型。
Marjan Venema

2
@ imel96:互联网从未严格过这一事实正是导致难以支持各种浏览器和服务器被迫与无效html向后兼容的事实,因为那里存在着太多的麻烦(很遗憾,它仍在创建中)。
Marjan Venema

9

您所说的“ RESTful JSON API”是什么意思-我认为这里的第一个问题是您正在混淆概念(或者可能是您和“供应商”中的技术同行之间的某个人)。

RESTful API(无论您是不是完全处于1级还是3级或更高水平,请参见http://martinfowler.com/articles/richardsonMaturityModel.html)都是关于您与API交互的方式,而不是发送或接收的内容的格式。它甚至与协议或传输机制无关...

类似地,JSON API是支持使用JSON作为数据格式的API-它可能会或可能不会轻松,它可能会或可能不会使用HTTP来实现,并且(这是关键点)它可能会 或可能不支持JSON只。

一个在HTTP上运行的优质 API(可以合理地假设您在上下文中谈论的是通过HTTP公开的api)应允许您请求多种格式的内容,并且这些格式可以(可能应该)包括HTML以及JSON和XML。为什么?嗯,这将使学习API变得容易得多,从概念上讲,它可为任何目的提供基于即时浏览器的UX,等等。

有趣的问题就变成了,如果调用了我支持多种内容格式的API而不告知客户期望的格式是什么,那么它将返回哪种格式...?这倾向于宗教观点-但是HTML给提供者提供了包括有用信息的选项(例如“记住要设置内容接受标头”)。

为了回答这个问题,一个API,一个宁静的API和一个支持json的API应该绝对能够返回HTML(如果这是所请求的内容)。


1
我理解了您的两点,并相应地编辑了我的问题。服务是RESTful的事实并不重要,我已经详细说明了客户端在每个请求中都接受“ application / json”。
phillip.darley

我会说“ RESTful JSON API”具有非常明显的含义。
gnasher729

1
我要说的是,我的老师付出了巨大的努力,以确保我们理解为什么“从不假设”是成为优秀程序员的关键部分
Murph 2015年

5

客户端始终使用“ application / json”的接受标头和“ application / json”的内容类型发出请求

是的,这是正确的做法,但这并不意味着供应商会在意。尽管我完全理解您的无奈,但因为我还认为JSON服务应始终提供JSON响应,但是有很多例子并非如此。

在整个项目中,相同的做法已应用于两个不同的供应商和两个不同的服务。我发现自己必须证明为什么需要更改服务。供应商表示,客户端应对此进行处理,甚至我选择的REST库也受到了质疑(RestEasy),因为默认情况下它不应对此问题。

好吧,我必须同意供应商的意见。这是他们的服务,只要他们清楚地记录了使用它的特殊情况,那么您就不能强加他们对其进行更改。这对他们来说是不利的,因为开发人员采用API的速度会很慢,并且如果他们听了开发人员的需求,那么他们会对其进行更改,但是可悲的是,没有规则要求他们必须遵循标准。

问题是我缺少什么吗?

请求标头没有任何意义,除非它们在另一端被正确中断。我知道,如果我使用PHP开发Web API,则会遇到请求标头。我可以随心所欲地回应。而在IIS中使用C#配置的服务可以更轻松地处理请求标头,它们的类型以及处理响应类型。这与供应商用来构建API的工具有很大关系。

我对此很着迷吗?

是和否。我有一些开发人员朋友,他们将无法超越。他们会被问题所困扰,并且无法继续执行其他任务,直到API以他们期望的方式工作为止。现在这很古怪。

这是一个问题,因为供应商创建了“更多工作”来完成您的任务。任何人都会对此感到沮丧。我知道我会的。

在这种情况下,可以使用不具有application / json内容类型的JSON API吗?

绝对可以,但这不是一个好习惯。

客户端只能告诉服务器a的上下文类型request是什么。它无权强制的内容类型response。客户端只能通知服务器它将accept收集可能的内容类型。

标头字段定义

接受请求标头字段可用于指定响应可接受的某些媒体类型。接受标头可用于指示该请求特别限于一小部分所需类型,例如在请求嵌入式图像的情况下。

客户端可能会请求的图片image/jpeg,但服务器会以响应,text/html并提供状态代码“ 404如果未找到图片”。服务器也可能响应不正确。那里有许多Wordpress网站可以响应text/html200提供未找到文件页面的状态代码。

现在,这是服务器方面的所有BAD练习。我想告诉您的是,这是绝对可能的,并且经常发生。人们在配置这些东西时不知道他们在做什么。

参考将不胜感激。您如何从商业角度解决这种情况?

我在几个项目中遇到了这个问题。您将postJSON数据发送到服务器,它会返回JSON或HTML响应。

知道响应中的类型并不是什么大问题。如果第一个字符是{或者[你可以假设JSON。如果是这样,<您可以假定HTML。这就是我过去的处理方式。有时,编写API的程序员会完全了解HTTP标头。一切都作为text/html回应而返回。如果幸运的话,他们将Apache配置为默认值text/plain,有时可以提供帮助。

这些问题是存在的,并将在未来很长一段时间内继续存在。服务器到服务器的通信到目前为止是不受管制的活动。没有哪个管理机构会从工会中将供应商赶出给出错误HTTP响应的服务器。


这与@Marjan Venema的答案一致,但是您提出的另一个关键点是有关此行为的文档。更令人沮丧的是,供应商尚未记录此行为。内容类型根据会话状态而有所不同,但是仅记录了JSON响应。
phillip.darley
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.