问题描述
我有一个REST API来管理一个简单的值键.
例如,Get请求可以返回以下内容:
{ "keyA": "valueA", "keyB": "valueB" }
有一个端点,可以用请求正文中的新地图代替地图.例如,该地图可以用新的地图替换:
{ "keyC": "valueC" }
这将删除键" keya"和" keyb",并添加" keyc".我们正在辩论的问题是,是否应允许PUT请求发送空的地图{}以完全清除地图,以便没有剩余的密钥.应该阻止这一点吗?这是否遵循休息惯例?
推荐答案
这不是针对休息的问题,而是它实际上是针对HTTP作为REST体系结构方法应用程序使用的默认传输协议.根据 rfc 7231 4.3.4 服务器
应验证PUT表示与服务器对目标资源所拥有的任何约束是一致的.
...
当PUT表示与目标资源不一致时,Origin Server应该通过转换表示或更改资源配置或使用适当的错误消息响应足够的信息来解释为什么表示表示为什么不适合使用,则原点服务器应使其保持一致. .
我承认这有点含糊,留下了足够的解释空间,但是我觉得无论您是否希望空体成为资源的有效状态,这都或多或少取决于您.如果您认为它应该不允许空体简单地返回409 Conflict响应,表示请求为什么失败.
需要在此处添加另一个注释:休息将重点放在媒体类型的使用上.媒体类型是形成有效文档的元素的句法和语义描述.如果将其与HTML进行比较,即您会注意到它定义了某些元素何时有效地放入文档中以及要使用哪种句法结构.这里的几乎所有文档都应该做同样的事情.因此,媒体类型定义了某些元素的约束,什么不是. A PUT请求应根据媒体类型中定义的约束来验证接收的有效载荷,以确定是否可以将冲突或表示形式转换为其他媒体类型格式.
application/json在休息方面是一种非常弱的介质类型,因为它只是定义了句法结构.它甚至不支持指向其他文档的链接.有几个扩展名,例如 application/hal+json ,它在链接关系上定义了语义仍然没有定义所需元素的语义.
这正是菲尔丁提到
的原因REST API几乎应该花费所有描述性的努力来定义用于表示资源和驱动应用程序状态的媒体类型,或定义用于现有标准媒体的扩展关系名称和/或启用超文本的标记类型. ( source )
)
其他推荐答案
这是否遵循休息惯例?
休息对代表的说法相对较少,除了应该标准化的事实.因此,例如,休息会考虑使用 application/json 很棒,因为它具有一个标准,因此也可以说JSON的其他工具也可以理解您的表示.
和..这一切都必须说.
收到有效载荷中有有效JSON表示的PUT请求后,您对此进行了操作 - 特别是,无论是否允许,它是一个实施细节.保证您的服务器对其存储的表示形式等等.
.例如,在远程创作上下文中,您的服务器实际上只是充当愚蠢的数据存储,然后是 Course ,存储一个空的JSON对象是有效的.
另一方面,如果该JSON表示应该描述带有所需元素的消息,则不,您可能不想在那里允许一个空对象. (在这种情况下,您可能不会使用应用程序/JSON,而是一些供应商类型).
问题描述
I have a rest API for managing a simple map of keys to values.
For example, the GET request could return the following:
{ "keyA": "valueA", "keyB": "valueB" }
There is a PUT endpoint that replaces the map with a new map in the body of the request. For example, the map can be replaced with a new map:
{ "keyC": "valueC" }
This removes keys "keyA", and "keyB", and adds "keyC". The question that we are debating is whether or not the PUT request should be allowed to send an empty map {} to clear out the map altogether so it has no keys left. Should this be blocked? Does any of this follow REST conventions?
推荐答案
This is less a question targeted towards REST then it is actually targeting HTTP as the default transport protocol used by applications following a REST architecture approach. According to RFC 7231 4.3.4 a server
SHOULD verify that the PUT representation is consistent with any constraints the server has for the target resource that cannot or will not be changed by the PUT.
...
When a PUT representation is inconsistent with the target resource, the origin server SHOULD either make them consistent, by transforming the representation or changing the resource configuration, or respond with an appropriate error message containing sufficient information to explain why the representation is unsuitable.
I admit that this is a bit vague and leaves plenty of room for interpretation but I feel that it's more or less up to you whether you want an empty body being a valid state of the resource or not. In case you think it shouldn't allow an empty body simply return a 409 Conflict response indicating why the request failed.
A further note needs to be added here: REST puts focus on the usage of media types. A media type is a syntactical and semantical description of the elements forming a valid document. If you compare that with HTML i.e. you will notice that it defines when certain elements are valid to be put into a document or not and which syntactial structure to use. The same should be done for almost any document here either. The media type therefore defines constraints on certain elements and what not. A PUT request here should validate the received payload against the constraints defined in a media type to determine whether a conflict arrose or the representation may be converted to an other media type format.
application/json is a very weak media type in terms of REST as it just defines the syntactical structure. It doesn't even support links to other documents to start with. There are a couple of extensions like application/hal+json that define the semantics on link relations though this will most likely still not define the semantics of elements you require.
This is exactly why Fielding mentioned that
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. (Source)
其他推荐答案
Does any of this follow REST conventions?
REST says relatively little about representations, other than the fact that they should be standardized. So, for instance, REST thinks using application/json is great, because it has a standard, and so other tools that also speak JSON can understand your representations.
And.. that's about all it has to say.
Once you receive a PUT request with a valid JSON representation in the payload, what you do with that -- and in particular, whether or not it should be allowed -- is an implementation detail. What promises is your server making about the representations that it stores, and so on.
For instance, in remote authoring context, where your server is really just acting as a dumb data store, then of course it's valid to store an empty JSON object.
On the other hand, if that JSON representation is supposed to describe a message with required elements, then no, you probably don't want to allow an empty object there. (In that case, you probably wouldn't be using application/json, but some vendor type).