Restful web服务...使用Put还是Post进行更新

3
我有一个restful webservice,我正在编写一个新的方法调用。这个新方法的目的是将一个人的状态撤销为"NO"。
请求中需要发送的只有一个Person_Id,这个Person_Id的状态需要被改变成"NO"。
我应该使用PUT还是POST来执行此操作?
如果我使用PUT,我可以仅将person_id作为路径参数发送,并且完全不使用xml。(像:http://serverName/PersonServices/Person/123456),在服务层中,我的代码如下。
    @PUT
    @Path("/Person/{person_Id}")
    @Consumes("application/xml")
    @Produces("application/xml")
    public JAXBElement<GetUsageTokenType> updateLicenseStatus(
            @PathParam("person_Id") final Long personId) {

            //code to change the status
     }

我是否应该使用POST来实现这个功能?如果我使用POST,需要发送xml格式的数据吗?


这是关于POST和PUT的W3C HTTP RFC:http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 - Jesse Webb
这里有一个关于REST中PUT与POST的类似问题:https://dev59.com/HHRB5IYBdhLWcg3wa2q2 - Jesse Webb
3个回答

3
如果您查看哪些HTTP方法与哪些CRUD方法匹配?,那里显示了映射。
Create = PUT with a new URI
         POST to a base URI returning a newly created URI  
Read   = GET  
Update = PUT with an existing URI  
Delete = DELETE

如果您阅读每个动词的定义的 HTTP RFC ,您就会明白为什么......
回应中说:

我能不能只将person_id作为路径参数发送,而不使用任何xml

理想情况下,您的URL

http://serverName/PersonServices/Person/123456

应该是

http://serverName/PersonServices/RevokePerson/123456

这将有助于可维护性,如果您不想传递任何XML / JSON /等,但RESTful服务中是否具有人类可读的URL是一个长期争论的问题
作为评论中所提到的,RESTful API 应该专注于内容而不是操作。例如,请参阅:为什么在 REST 实现中在 URI 中包含动作动词会违反协议?
因此,您可以将一个人传递到 URL 中,并根据 HTTP 动词执行相关的 CRUD 操作。如果您只想传递一个 ID,则必须猜测在 PUT 到 ID 时要采取哪个更新操作...除非您知道永远不会有任何其他更新。

1
我认为RESTful API的URL不应该包含动作动词。你建议的URL中包含RevokePerson,这使其不符合资源导向的原则。 - Jesse Webb
就像我所说的,这是一个长期争论的问题。如果您只想在URL中指定ID,如何对同一人进行两个不同的更新?我想你应该将序列化后的Person放入PUT请求中,这样就可以更新(在此情况下是通过撤销许可证)另一端的Person了。我想我对回应“我是否可以只将person_id作为路径参数发送,而不使用任何xml”这个问题没有表达清楚。 - Paul D'Ambra
我同意,这个话题仍然有很多活跃的讨论。我曾尝试在URL中使用动作动词,结果导致了许多(数百个)不同的URL以各种方式修改相同的资源。结果证明这是一个糟糕的想法,所以我只是试图引导其他人不要陷入同样的困境。但这只是我的观点,对我失败的事情可能对别人来说是正确的,这就是为什么我没有投反对票的原因。;) - Jesse Webb

0

这取决于你如何实现你的服务器,但是遵循适当的REST原则,你会想使用PUT。


0

我建议您向以下URL进行POST

http://serverName/PersonServices/Person/123456

但是您不应该发送一个空的请求体,而是应该按照标准的POST请求参数语法,将希望更新的字段包含在请求体中。

例如:status=NO

对于单个(或多个)字段的更新,我认为这是最好的方式。例如,如果您需要在请求中更新一些字段,可以使用...

firstName=Jesse&status=YES

这样,URL就维护了它们对资源的对应关系(而不是像包括RevokePerson或类似路径参数的操作那样)。这样做提供了最大的灵活性,同时避免了通过为每个所需操作创建大量不同的URL端点来污染API的问题。


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