简体   繁体   中英

How to properly structure REST endpoints for PUT and POST

I have a REST service for managing users.

HTTP GET("/users") - get all users
HTTP GET("/users/{id}") - get data for specific user

When changing something about the user I'm not sure how structure the paths for PUT/PATCH.

Option 1:
HTTP PUT ("/users") and transfer the user data (id, first name, last name) in the request body
HTTP PATCH ("/users") and transfer the user's ID and PASSWORD in the request body

Option 2:
HTTP PUT ("/users/{id}") and transfer the user data (id, first name, last name) in the request body
HTTP PATCH ("/users/{id}") and transfer the user's ID and PASSWORD in the request body

Option 3:
HTTP PUT ("/users/{id}") and transfer the user data (id, first name, last name) in the request body
HTTP PATCH ("/users/{id}/password") and transfer the user's ID and PASSWORD in the request body

@RequestMapping(value = "/users") public interface 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);

I'm not sure which of these approaches is the best. I can get all the data from the request body every time but I'm not sure what should be the best path to create. Using "/users/{id}" to change details about the user makes sense because I'm changing for a specific user but since I can read the ID from the request body, the path variable is redundant here.

It's the same confusion when changing the password. Since I have just one Patch endpoint under "/users" should I still use the "/users/{id}/password" or maybe I should delete the "/password" part?

When changing something about the user I'm not sure how structure the paths for PUT/PATCH.

Both PUT and PATCH are document editing requests. "Please make your representation of this resource look like mine".

In an idealized form, I would have some sort of HTTP aware document editor. I would GET a representation of the resource from you, make edits to my local copy, then send a representation of my local copy back to you.

Getting useful work done is a side effect of passing these documents around. See Jim Webber's talk .

Options 1, I think we can simply reject on first principles. If the resource identified by /users is a collection of users, then trying to replace its representation with that of a single user is not a step in a useful direction. Semantically, if you wanted to edit or insert a user by interacting with the /users resource, you would do that by either (a) making an edit to the representation of the collection, and sending the entire representation back (PUT), or by sending a description of the diff back to the server (PATCH).

Option 2, has a subtler issue -- if the password is part of the representation of the /users/id resource, then the password should also be part of the body of the PUT request. PUT and PATCH are different ways of passing our local representation of the resource back to the server; we shouldn't be thinking of them as having different information about the resource.

It's perfectly reasonable to separate the password into a different resource from the rest of the user. Unless the representation of the password resource is very large relative to the password itself, I would expect PUT rather than PATCH to be used in most cases.

So you are suggesting that option 3 would make the most sense?

Not quite - both resource designs (either with all of the information available in one resource, or with the information divided between two resources) are fine. You pick one, and then make sure the idioms you use for updating the resource(s) are appropriate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM