1

Designing API using JSONAPI 1.0 standard there is no PUT method. There is only POST method for create resource and PATCH for partially update. We have use case where user can send request to the server and if resource doesn't exist then must be created otherwise updated. RFC describe such method as a PUT. Next quoting mentioned RFC 5789 standard for PATCH there is information:

"If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc."

Is it good idea to have PATCH method for update and create resource? Which standard should be used to support both PUT and PATCH methods (maybe OpenApi)?

How to interpret RFC description?

Best Regards

Papub
  • 75
  • 1
  • 9

2 Answers2

2

We have use case where user can send request to the server and if resource doesn't exist then must be created otherwise updated.

The right answer, in this case, is almost certainly going to be to POST your request to the collection resource, and let the server figure out the "right" thing to do.

A resource can be created by sending a POST request to a URL that represents a collection of resources.

Using PUT to create a resource assumes that the client can/should guess what the correct identifier for the new resource should be. If we're not giving the client that authority/control, then the request needs to instead use a stable target-uri, and the server computes the side effects on other resources.

In JSON:API, the server gets to control the choice of URI for the new item.

POST /photos HTTP/1.1
Content-Type: application/vnd.api+json

...

HTTP/1.1 201 Created
Location: http://example.com/photos/550e8400-e29b-41d4-a716-446655440000

If the API were supporting PUT semantics, an equivalent change would look something like

PUT /photos/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Content-Type: application/vnd.api+json

HTTP/1.1 201 Created

But JSON:API has decided that PUT isn't interesting yet. Reading between the lines, the authors decided that PUT should be reserved until more implementations demonstrate that they understand the HTTP spec.

So instead you have POST to the collection for the create, and PATCH on the item to for partial or complete replacement.

That in turn implies that if the client doesn't/cannot know that a resource already exists, that it should POST to the collection. The server, in turn, should be aware that the resource may already exist, and do something sensible (replace the representation of the resource, redirect the client to the resource, etc). How the server achieves that would be an implementation detail.

Looking into Internet deal with REST HTTP methods I have never seen that PATCH can be used for resource creation therefore I am surprised that JsonApi forgo PUT method.

PATCH can certainly be used for resource creation -- see RFC 5789

If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc.

It's an uncommon choice, because PUT semantics are a better fit for that use case. Choosing to support PATCH, but not PUT, is weird.

I am surprised that JsonApi forgo PUT method

I am also surprised.

It might be possible to resolve your concerns by registering a new profile, encouraging the community to adopt a common pattern for the semantics that you need.

Community
  • 1
  • 1
VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91
  • Yeah, that things are clear for me but it is in opposition what wrote Roman Vottner below. Using JsonAPI and having 100 POST requests to resources where a half of them exist we ultimately end with 150 request. 50 of them will be rejected by server to use PATCH instead. Looking into Internet deal with REST HTTP methods I have never seen that PATCH can be used for resource creation therefore I am surprised that JsonApi forgo PUT method. In other side in their documentation there is no information that we can use PATCH to create and how the response should look like. – Papub Jul 24 '19 at 15:52
  • @Papub I don't think that Voice necessarily stated something different than I did. S/He described just the take on `appliction/vnd.api+json` explicitely while my post contained more general information on two common patch methods used in practice. A media type just defines the syntax and semantics on how to transform the state of a resource into something that can be sent to and processed by an other party. The same data can usually be represented in multiple forms, i.e. some XML or JSON slangs. It is part of content type negotiation to agree on one type and format the data accordingly – Roman Vottner Jul 24 '19 at 16:27
  • Roman - you are right but I think JsonApi not only describe syntax and semantics but also other things we have to respect if we want use this standard. Otherwise we could create PUT method which resolve discussion and in request we could add appliction/vnd.api+json to be correctly interpreted by the server side. – Papub Jul 24 '19 at 16:45
1

According to Postel's law one should be conservative in what you do, be liberal in what you accept from others.

Two common media-types used with PATCH are application/json-patch+json (a.k.a. JSON Patch) and application/json-merge-patch+json (a.k.a MergePatch).

MergePatch defines a couple of rules that determine whether a part needs to be added, removed or updated. The spec defines that a request received of that type needs to be processed by calling a function that takes in two arguments, the target resource and the representation received. The target itself might be either a JSON value or undefined. If the resource does not yet exist it is undefined and will lead to all of the values in the received patch document to be added to the yet undefined resource. This is basically your resource creation then.

JSON Patch, in contrast to MergePatch, is specified to only operate on JSON documents. There is no mention how the patch needs to be applied in case no resource was yet available. This makes somehow sense if you look at the operations is offers, such as test, remove, replace or move that only work if there is a counterpart in the original JSON document availalbe. This media-type is quite close to the actual PATCH definition in that a client sends a set of instructions, which were previously calculate by the client, that need to be applied atomically by the server. Either all or none of the changes are applied. Here a client should have already fetched the current state of the target resource beforehand, otherwise it wont be able to calculate the necessary changes to transform the current representation into the desired one. So applying a representation of that media-type only makes sense if there is already a resource available. If the client saw that no target resource is yet available it simply can use POST then to create the resource. If a client though sends a patch document containing only add operations I'd create a JSON representation and add all of the fields accordingly though.

As you see there are two different takes on how PATCHing can be done in HTTP. One being very close to the original idea of how patching is done in software engineering for decades while the other method being a more pragmatic approch to partial updating remote resources. Which one you use or support (in best case both) is your choice.

Community
  • 1
  • 1
Roman Vottner
  • 12,213
  • 5
  • 46
  • 63
  • Thank you for answer. As I see in provided RFC the target is Json Document? "A JSON merge patch document describes changes to be made to a target JSON document". So If we accept application/vnd.api+json and we respond in application/vnd.api+json we assume that our target is json document right? I understand correctly? – Papub Jul 24 '19 at 15:58
  • Both mentioned media-types, JSON Patch and MergePatch, operate on JSON representations. A media-type similar to JSON PATCH but for XML documents is [XML Patch](https://tools.ietf.org/html/rfc7351). [IANA](https://www.iana.org/assignments/media-types/media-types.xhtml) lists 3 further media-types related to patching though one of them seems similar to XML Patch while the other two are for YANG data nodes. If you have special needs you can also define your own media-type and register it with IANA and eventually provide libraries to use your patch methods more intuitively – Roman Vottner Jul 24 '19 at 16:12
  • But "JSON:API requires use of the JSON:API media type (application/vnd.api+json) for exchanging data." therefore we can not use other media type. You have provided common media-types but I also wonder if standard PATCH call can create resource. Using media types listed above I see it's possible but what about PATCH without those media types? – Papub Jul 24 '19 at 16:28
  • [RFC 5789](https://tools.ietf.org/html/rfc5789) leaves that decission basically to the more concrete "implementations". In general, it is often benefitial to allow as much as possible, i.e. resource creationg via PATCH, when dealing with incoming requests but be strict when sending out responses (see Postel's law). But it is also benefitial that a server/API supports a multitude of different media-types to reach a broader audience. Of course, if a server only supports a limited set of media-types a client won't be able to interact with the server unless special support is added to it – Roman Vottner Jul 24 '19 at 16:39