I know many best practices questions have been asked on this topic, but I'm not able to find exactly what I'm looking for. Let's say I want to have an endpoint to join or leave a chatroom. My thought was to have a request like:
PATCH /api/chatroom/{roomId}?action=join|leave
This seems solid to me, because PATCH is generally used to partially update a resource. In this case, I'm updating the chatroom resource, either removing or adding a member. However, I don't love this, because of two reasons:
- Having a query param like
action
feels a bit clunky. The API user has to know the possible values foraction
, and invalid values have to be explicitly handled server side. - Error handling is quite different for
join
vsleave
. A join request will return an error if the user has not been invited to the chatroom. On the other hand, a leave request will return an error if the user is not a member of the chatroom. This differences makes me feel like these should be seperate endpoints.
Would it be preferable to have two endpoints like this?
PATCH /api/chatroom/{roomId}/join
and PATCH /api/chatroom/{roomId}/leave
This feels worse, because join
and leave
are not resources. However, I also like that this separates things into two endpoints. What's the RESTful way to do this?
CodePudding user response:
PATCH /api/chatroom/{roomId}/join and PATCH /api/chatroom/{roomId}/leave
I refer this way too due to single responsibility.
Resources are not always required, manipulating somethings are oki too.
/api/cart/empty-all
/api/cart/remove-all
...
CodePudding user response:
This seems solid to me, because PATCH is generally used to partially update a resource.
Yes... but we don't generally invest new resources just to patch them.
TL;DR: it is okay to use POST. That's what we did on the web back when everything was HTML and forms.
PATCH, like PUT, should be understood as POST message with additional constraints. POST gives general purpose clients very little context about what is happening; but PATCH is more specific - patch says that we are proposing an edit to the request-target, and the payload is a "patch document" that describes the changes to the representation.
In other words, PATCH (like PUT) is a method we would use if we were trying to correct a spelling error on a web page.
The key idea is well described by Webber 2011: PATCH is part of the general purpose transfer of documents over a network domain. The useful business activities (like joining and leaving chats) are side effects of the manipulation of the documents in the resource model.
You might imagine, for example, a document that includes a list of all participants in a chat - if you yourself want to join the chat, you signal that by asking the server to add your name to its list of participants.
A straight forward design would be to have the list of participants in the chatroom itself (?), so the request might look like:
POST /api/chatroom/12345 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=join&user=Bob
If /api/chatroom/12345 was a resource with a JSON representation, then we might achieve a similar result by patching a list of participants in the chatroom resource
PATCH /api/chatroom/12345 HTTP/1.1
Content-Type: application/json-patch json
[
{ "op": "add", "path": "/participants", "value": "Bob" }
]