Reputation: 1892
There are users
in the application which have preferences - favourite authors. A user can change this list. Authors are in the authors
collection of a User
entity:
@Entity
public class User {
@Id
....
@ElementCollection
private List<String> authors=new ArrayList<>();
}
A user can edit his profile and change this list by adding or removing an author.
On the one hand, adding or removing authors means just editing a profile, that's why currently I'm using a PUT
method:
@PutMapping("/api/profile/author/add")
@PutMapping("/api/profile/author/remove")
But I'm not sure if this is correct. Another variant is to use POST
and DELETE
methods as the user adds and removes items:
@PostMapping("/api/profile/author/add")
@DeleteMapping("/api/profile/author/remove")
So what is correct variant and what's the reason?
Upvotes: 1
Views: 5136
Reputation: 57239
PUT is a request method with remote authoring semantics; you would normally expect that the target resource will be the thing that you are editing.
In other words, the @PutMapping would normally be using the same URI (or URI template) as the @GetMapping.
GET /profile
// Make local edits to the document
PUT /profile
If the list of favorite authors is a separate resource, that's also fine. The pattern would be the same:
GET /profile/authors
// Make local edits
PUT /profile/authors
The point being that I can use any HTTP aware editor to make changes to a remote document. The messages aren't specific to "list of favorite authors"; as far as the machines are concerned, it's just another document.
Using POST instead of PUT is fine -- when the world wide web began, all unsafe messages were POST, and that was catastrophically successful. It is OK to use POST.
Upvotes: 1
Reputation: 2558
If you check RFC 7231 Section 4.3.4 PUT, you'll see that
4.3.4. PUT
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
In simple terms, PUT is when you either create a resource at url, or replace it completely (a file upload is an easy example).
In your case, an author is not entity in itself (I can see that its just a String
and the list is an @ElementCollection
). Which means, when you add an author, you're modifying the User
entity. i.e, you're not
creating or replacing the 'User'. Therefore, PUT is not appropriate for adding the author.
PUT is also not for deleting an entity. You should consider DELETE for that.
Now, RFC 7231 Section 4.3.4 POST says this:
4.3.3. POST
The POST method requests that the target resource process the
representation enclosed in the request according to the resource's
own specific semantics. For example, POST is used for the following
functions (among others):
- Providing a block of data, such as the fields entered into an HTML form, to a data-handling process;
- Posting a message to a bulletin board, newsgroup, mailing list, blog, or similar group of articles;
- Creating a new resource that has yet to be identified by the origin server; and
- Appending data to a resource's existing representation(s)
Again, in simple words, POST can be a request to initiate an action at the server. The last two in the example list above applies to your case - you're appending or creating an author. Which means POST is appropriate for adding the author.
Conclusion:
Use POST and DELETE for adding and deleting authors.
On a side note, you should probably get rid of the add
and remove
at the end of the url. Let the HTTP Methods POST and DELETE differentiate the actions.
So it should be
@PostMapping("/api/profile/author")
@DeleteMapping("/api/profile/author")
Upvotes: 6