multitaskPro
multitaskPro

Reputation: 571

Path param vs query param in PATCH request

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:

  1. Having a query param like action feels a bit clunky. The API user has to know the possible values for action, and invalid values have to be explicitly handled server side.
  2. Error handling is quite different for join vs leave. 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?

Upvotes: 1

Views: 4258

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57239

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" }
]

it's also better to include the information of the patch in the body, instead of the URL.

The URI identifies the resource; the patch document describes the proposed changes to the resource identified by the URI.


I should lean towards using PATCH on the resource itself, and pass a JSON representation of the changes I'm looking for?

... if remote authoring is the right kind of interface for your context.

One way of thinking about this: in a remote authoring interface, it probably shouldn't matter whether changes are made to your resources via PUT or via PATCH. They are both expressing the same basic idea (please make your copy look like my copy).

Which means that deducing the intended "business activity" means identifying the change(s) in the documents and then doing the right thing. Contrast this with POST, which is more suitable for "I'm going to tell you what I want, you figure out how the document should change".

Upvotes: 1

Huy Nguyen
Huy Nguyen

Reputation: 2061

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
...

Upvotes: 0

Related Questions