我和我的同事正在实施一些RESTful HTTP服务,我们正在努力确保我们遵循规范,并且b)在规范缺乏细节的情况下做“正确”的事情。 / p>
以下是我们遇到的特殊情况,并正在寻求社群的意见:
假设您有一个资源/ People / Bob,并且您的客户端将使用PUT更新它。服务器可以在application / json和text / html中为/ People / Bob生成表示。服务器可以在application / json中解释/ People / Bob的表示。
鉴于此要求:
PUT /People/Bob Content-Type: application/json Accept: application/xml { name: "Still Bob" }
服务器无法生成XML表示,但它可以处理传入的JSON。所以我们知道正确的答案是服务器返回状态406。
问题是:服务器是否应该对/ People / Bob执行更新?
答案 0 :(得分:2)
+1 REST哲学。
如果没有HTTP规范的详细知识,我只需选择其中一个选项并记录窘境和选择。
我的偏好是服务器无法按要求进行响应,因此它根本不应处理任何请求。
但是在某些情况下这可能不起作用,所以你可能不得不做相反的事情。
答案 1 :(得分:2)
问题是:服务器是否应该对/ People / Bob执行更新?
从the HTTP spec,406意味着:
请求标识的资源只能生成响应实体,这些响应实体的内容特征根据请求中发送的接受标头不可接受。
除非是HEAD请求,否则响应应该包括一个实体,其中包含可用实体特征和位置的列表,用户或用户代理可以从中选择最合适的实体特征和位置。实体格式由Content-Type头字段中给出的媒体类型指定。根据用户代理的格式和功能,可以自动选择最合适的选择。但是,本规范没有为此类自动选择定义任何标准。
Note: HTTP/1.1 servers are allowed to return responses which are not acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to determine if it is acceptable.
如果回复可能是不可接受的,那么用户代理应该暂时停止接收更多数据,并询问用户是否有进一步行动的决定。
关于HTTP / 1.1的中间说明可能是你的答案。我读到它说:“当用户代理在Accept标头中指定application / xml,选择任何合适的内容类型时,你可以返回200响应PUT请求给/ People / Bob,并且这个结果可能比返回406。“
在这种情况下,PUT将在服务器上成功,返回200,但客户端将获得application / json表示。客户端需要能够通过确保它理解Content-type头中给出的媒体类型来处理这种可能性,并且如果不理解则以明确定义的方式运行。
但无论如何这总是如此。
还有一件事:您可能想要考虑不使用普通的媒体类型,如application / xml和application / json,而是定义您自己的自定义媒体类型,可能基于XHTML或JSON。所有client-server coupling in a RESTful application都通过媒体类型发生。如果没有足够丰富的媒体类型来捕获您的域概念,那么您就不能完全指定REST API。
答案 2 :(得分:1)
我会在理论上争论'是',但对于现实世界的应用来说'不'。
如果出现错误,我会看到不处理的逻辑。由于你返回406而不是500,我知道这不是我提供的数据中的错误,而是结果呈现给我的方式。
也就是说,有些应用程序不会检查错误代码;他们只会看到它返回错误而不是它要求的XML,并假设交易失败。
我认为你不处理application / xml不是一个实际问题,但是出于问题的目的 - 如果这实际上是作为一个真实世界的服务部署,你几乎肯定希望能够拥有一个XML表示,因为(我怀疑)是最常见的RESTful交互,许多调用者可能会被硬编码为使用XML。
总结一下:如果你实际上没有提供application / xml,那么我会说,不要执行更新。如果您正在处理所有标准,但是您正在计划用户要求申请/ fooSomethingNonStandard的意外事件,那么请继续执行更新,但请确保您使用406进行回复。
答案 3 :(得分:1)
摆脱困境的一个方法是成功PUT
返回204(无内容)。这样,客户端的Accept
标头与是否执行更新的问题无关。
“RESTful”(或至少“HTTP拥抱”)客户端将知道不更新其当前“页面”,并且必须执行GET
才能刷新其视图只需 - PUT
资源。当然,Accept
上的GET
标题与更新原子性有关。
答案 4 :(得分:0)
我会成功并使用Rich上面建议的方法或406返回200并失败。该协议不允许将2xx(成功)与4xx(错误)代码混合的更细致的方法,因此可以读取4xx意味着不成功。