Reputation: 4145
I don't quite grok how to sensibly structure a REST (or REST-like) API.
Imagine an API for creating and sending out newsletter emails. You might have the following nouns/resources: newsletters (subject, body, etc.), mailing lists (collections of recipients), and recipients (email addresses and associated data).
So you could use PUT to create a resource and be returned its ID:
/newsletter
/list
/user
You could obtain information on a resource using GET:
/newsletter/[id]
/list/[id]
/user/[id]
You can update an existing resource using PATCH (or should this be POST?):
/newsletter/[id]
/list/[id]
/user/[id]
You can delete a resource using DELETE:
/newsletter/[id]
/list/[id]
/user/[id]
Is the above correct?
What endpoints are sensible for actions like sending a newsletter to a list, adding a user to a list?
Does the following make sense, and is it RESTfull?
/newsletter/[newsletter_id]/send/[mailinglist_id]
/list/[list_id]/add/[user_id]
/list/[list_id]/remove/[user_id]
Is it redundant or unhelpful to have list/[id]/add/[id]
and list/[id]/remove/[id]
endpoints for lists, when users could be added or removed via PATCH at /list/[id]
?
What about searching for a users' ID via a property like email address or name? Or getting a list via an identifier like its name or when it was created?
Upvotes: 11
Views: 14056
Reputation: 12783
Is it redundant or unhelpful to have
list/[id]/add/[id]
andlist/[id]/remove/[id]
endpoints for lists, when users could be added or removed viaPATCH
at/list/[id]
?
It is bad/unhelpful. One of the ideas of REST is that the end points are resources and not a Remote Procedure Call (RPC). add
or remove
is suggesting a procedure to call.
Further GET requests should be side-effect free, that is, they don't do any updates. Further Roy Fielding explains GET as:
retrieval of information that should be a representation of some resource
So GET is only for retrieval, not for sending data (i.e. which user to add/remove).
The other very dangerous problem with list/[id]/remove/[id]
is that if a spider or your test framework is going around your site it could start deleting items.
Upvotes: 0
Reputation: 385
These verbs are often confused:
These things could be treated in the following way:
POST /newsletters/[newsletter_id]/mailinglists/[mailinglist_id]/mailingfacts
- performs sending the letters, it's like adding a fact of mailing to the collection
/lists/[list_id]/[user_id]
- adds a user to the list
/lists/[list_id]/[user_id]
- deletes the user from the list.
Upvotes: 1
Reputation: 26861
You pretty much nailed it, except with the /list/[list_id]/add/[user_id]
and /list/[list_id]/remove[user_id]
, because you have verbs in the URL - that is the purpose of the HTTP methods. Change them to, for example:
PUT (or POST) to /list/[list_id]/users/ for adding a user to the list
and
DELETE to /list/[list_id]/users/[user_id]
For search, I'd go with parameterized url for the list of resources, like:
/newsletter/?name=dfjkhskdfh
Upvotes: 8