我有一个用于管理用户的REST服务。
HTTP GET(“ / users”)-获取所有用户
HTTP GET(“ / users / {id}”)-获取特定用户的数据
在更改有关用户的某些信息时,我不确定PUT / PATCH的路径结构如何。
选项1:
HTTP PUT(“ / users”)并在请求正文中传输用户数据(ID,名字,姓氏)
HTTP PATCH(“ / users”),并在请求正文中传输用户的ID和PASSWORD
选项2:
HTTP PUT(“ / users / {id}”)并在请求正文中传输用户数据(id,名字,姓氏)
HTTP PATCH(“ / users / {id}”)并在请求正文中传输用户的ID和PASSWORD
选项3:
HTTP PUT(“ / users / {id}”)并在请求正文中传输用户数据(id,名字,姓氏)
HTTP PATCH(“ / users / {id} / password”)并在请求正文中传输用户的ID和PASSWORD
@RequestMapping(值=“ /用户”) 公共接口UserController {
@GetMapping(value = "/{id}", produces = "application/json")
User getUser(@PathVariable long id);
@PutMapping(value = "", consumes = "application/json")
void addNewUser(@RequestBody User ser);
@PatchMapping(value = "/{id}/password", consumes = "application/json")
void changeUserPassword(@RequestBody UserPasswordChange passwordChangeModel, @PathVariable String id);
我不确定哪种方法最好。每次都可以从请求正文中获取所有数据,但是我不确定应该创建什么最佳路径。使用“ / users / {id}”来更改有关用户的详细信息是有意义的,因为我要为特定用户进行更改,但是由于我可以从请求正文中读取ID,因此路径变量在这里是多余的。
更改密码时也有同样的困惑。由于我在“ / users”下只有一个Patch终结点,我还是应该使用“ / users / {id} / password”,还是应该删除“ / password”部分?
答案 0 :(得分:1)
在更改有关用户的某些信息时,我不确定PUT / PATCH的路径结构如何。
PUT
和PATCH
都是文档编辑请求。 “请使您对此资源的表示像我的一样。”
以理想的形式,我将拥有某种HTTP感知的文档编辑器。我会GET
代表您的资源,对我的本地副本进行编辑,然后将我的本地副本的代表发送回给您。
完成有用的工作是传递这些文档的副作用。参见Jim Webber's talk。
选项1,我认为我们可以简单地拒绝第一条原则。如果/users
所标识的资源是用户的集合,那么尝试用单个用户的资源替换其表示不是朝着有用方向迈出的一步。从语义上讲,如果您想通过与/users
资源进行交互来编辑或插入用户,则可以通过以下两种方法之一进行:(a)对集合的表示形式进行编辑,然后将整个表示形式发送回(PUT) ,或将差异说明发送回服务器(PATCH)。
选项2出现了一个小问题-如果密码是/users/id
资源表示形式的一部分,那么密码也应该是PUT
请求正文的一部分。 PUT
和PATCH
是将资源的本地表示形式传递回服务器的不同方式。我们不应该认为它们具有关于资源的不同信息。
将密码与用户的其余部分分离到不同的资源中是完全合理的。除非相对于密码本身,密码资源的表示形式非常庞大,否则我希望在大多数情况下使用PUT
而不是PATCH
。
因此,您建议选项3最有意义?
不太正确-两种资源设计(在一个资源中使用所有可用信息,或在两个资源之间分配信息)都可以。选择一个,然后确保用于更新资源的习惯用法是适当的。