Ekaterina
Ekaterina

Reputation: 1892

What is the correct method in REST API for adding an item to a collection - POST or PUT

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

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

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

Neeraj
Neeraj

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

Related Questions