如何进行REST-ful更新?

时间:2011-12-12 18:11:41

标签: rest

如果我有一个对象,请说Employee,我想提供两种不同的更新方式 - 更新效果评级或更新联系信息。

构建API的REST-ful方法是什么?我认为正确的方法是POST。

我担心的是,用户首先获取对象的两个部分(性能评级和联系信息),只更新一个部分,然后POST整个更新的对象似乎不够优雅。

我的另一个担心是发送一个只填充了某些字段的对象似乎不太优雅,因为对象的模式要求所有字段都完整,而省略字段只是为了支持POST。 I. e。它需要单独的模式来支持操作或没有模式 - 似乎都没有。

同样,使用标志来更新哪些字段也需要一个不同的模式来执行操作。

提供单独的方法并不适用于名词 - 动词范式。

如果要求REST API处理此类案例,它们应该如何看待? REST名词和应用程序实体之间是否需要多对一映射?如果是这样,我们是否将视图实体的PUT限制为代表应用程序实体的子集?

我不是在寻找黑客或不优雅的方式。我正在寻找REST理念认为正确的解决方案。提前谢谢!

5 个答案:

答案 0 :(得分:4)

我不确定这是否可以解决您的问题,但看看评级和信息也是资源我会像这样制作API(感谢taylonr模板:)

url/employees/{id}/[rating|info]

通过这种方式,您可以获得所有员工的代表,具有特定ID的员工,具有特定ID的员工的绩效评级以及具有特定ID的员工的联系信息。

创建具有初始化联系信息和绩效评级的新员工

POST url/employees { "id": "johnsmith", "rating": 4, "info": ["address": "street 1 a 1" , "email": "johns.old@mail.com"] }

更新2将适用于不同的POST

PUT url/employees/johnsmith/rating  { "rating": 5 }
PUT url/employees/johnsmith/info { "email": "john.smith@company.com" }

答案 1 :(得分:3)

我认为这取决于应该如何使用它。

如果您只是想做一些事情,比如简单地让客户端传递更新ENTIRE Employee对象所需的所有信息,那么您只需要公开一个端点,您就可以......

domain/employee/{employee_id}

像@taylonr解释的那样。对于您要向第三方公开的API,情况更有可能发生。你制作这样一个方法的原因是因为它允许第三方构建自己的功能来更新整个资源;然后传递给你。换句话说,拥有整个资源是一件好事;但如果你将它用于自己的网络应用程序,可能不是最好的。

但是,如果这是Web应用程序的后端,那么您将要做一些相关的事情;但是并不需要知道所有信息来执行预期的行动,那么你可以遵循这种范式:

domain/employee/{employee_id}/action

因此,例如,当我对您的帖子进行投票时,Stackoverflow正在使用的帖子是......

                         noun    noun verb verb
                           |       |     |  | 
                           |       |     |  |
http://stackoverflow.com/posts/8478829/vote/2

这样做的原因是因为您只需要URL和会话信息(服务器端的经过身份验证的对象),您就可以完成所需的一切。

你说那个

  

我的另一个担心是发送一个只填充了某些字段的对象似乎不太优雅,因为对象的模式要求所有字段都完整,而省略字段只是为了支持POST。 I. e。它需要单独的模式来支持操作或没有模式 - 似乎都没有。

但我不认为这是一个有效的问题。您只需使用"名词"而不是依赖客户端传递它想要更新的对象的所有信息。 part - posts/8478829 =并解析资源服务器端。

答案 2 :(得分:2)

为什么不做呢

PUT myuri/Employee/{id}

请求的主体有Employee对象。这样消费者可以更新他们想要的东西并将其交还给您。由于用户已经有了ID,你可以做一个PUT。

这就是我们通常在我工作过的API上做的事情。

回馈整个对象的好处是因为API需要知道用户拥有的版本是否是最新版本(例如,使用ETag)。如果消费者试图更新过时的东西,那么它应该失败。

答案 3 :(得分:2)

PUT到您获取的相同URI。

REST API可以在资源和事物之间建立一对一的映射。或者资源和事物之间的多对一映射。究竟是什么“事物”取决于你;它可以是您认为的应用程序实体,但如果它对它有意义则不必仅代表此类实体的一部分。

如果我是您的API的用户,我真的不关心您在实施中做了什么或不考虑实体,我关心您认为Web服务中的资源。

答案 4 :(得分:2)

另一种选择是使用相对较新的PATCH HTTP谓词,以及补丁/差异格式的自定义架构。这样可以避免污染PUT / POST的语义,并且更符合您的需求,即更新资源属性的子集。

否则,我会采用Topi Ojala的方法(如某人已经评论的那样交换PUT / POST)