简体   繁体   中英

REST how to POST or PUT without full entity(@RequestBody)

I have an Entity 'Vote' that has fields:

private Integer id;
private LocalDate date;
private LocalTime time = LocalTime.now();
private User user;
private Restaurant restaurant;

I know that for REST POST peferably i shoud use resourse pattern like this:

/votes

and in case of update:

/votes/{voteId}

Presumably i shoud receive full vote entity in my controller from frontend like this:

@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Vote> create(@RequestBody Vote vote)

But i dont need that to create or update that entity, i only need restaurantId like this:

@PostMapping
public void create(@RequestParam int restaurantId) {
        voteService.create(SecurityUtil.getUserId(), restaurantId);
    }

So, will be the right choice to use resourse pattern like this, or i'm wrong?

For POST create:

/votes?restaurantId=10

For PUT update:

/votes/{voteId}?restaurantId=10

You should change it to:

@PostMapping
public void create(@RequestParam("restaurantId") int restaurantId) {
    voteService.create(SecurityUtil.getUserId(), restaurantId);
}

You should mention the parameter name in @RequestParam("param_name")

Why not using path parameters? It is a bit strange to pass get parameters to POST and PUT.

@PostMapping("/{restaurantId}")
public void createPost(@NonNull @PathVariable(value = "restaurantId") String restaurantId) {
    voteService.create(SecurityUtil.getUserId(), restaurantId);
}

@PutMapping("/{restaurantId}")
public void createPut(@NonNull @PathVariable(value = "restaurantId") String restaurantId) {
    voteService.create(SecurityUtil.getUserId(), restaurantId);
}

So, will be the right choice to use resourse pattern like this, or i'm wrong?

"It depends".

The spelling of the URI doesn't matter to the machines; /0d905ca3-c848-4bc5-bc4a-658fbec88ab5 is a perfectly fine path to use. Human readable spellings are just a convenience for humans - a "RESTful" spelling like /votes isn't any more REST than using the UUID, but when the operators are pouring through logs trying to identify a traffic pattern, they will probably be happier with the second choice.

POST, as a method token, is fine. See It's Okay to Use POST (Fielding, 2009).

PUT , however, doesn't quite sound like what you want. Semantically, PUT means "replace the current representation of the resource with payload of the current message." It's a remote authoring method, which when paired with GET gives you a document store:

PUT is the method you would use on the world wide web to edit your home page, for example.

GET /home-page

(make changes locally)

PUT /home-page

And the body of that PUT request is the intended new version of the home page.

In your case:

PUT /votes/{voteId}?restaurantId=10

is supposed to have a payload that looks like what you would read if you did

GET /votes/{voteId}?restaurantId=10

It needs to be a complete representation of the resource.

That doesn't mean it needs to be a complete representation of the entity ; resources are a generalization of a document; a view into your entity's data. Remote authoring sends a new representation of the view, and it's the server's job to make the matching changes to the entity. See Jim Webber 2011 .

If you don't want to make your updates that way, that's fine -- but then you shouldn't be using PUT , as that defeats the point of having a common semantic with all other resources (you should use POST).

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