I’ve been working on Software Engineering for more than 3 years now. And I’m surprised, in these 3 years, I never face any PATCH endpoint yet, until now.
And because of that, I never really use the PATCH Method before, and never develop it either. I remember 3 years ago when the first time I asked my senior about the difference between PUT and PATCH was only the changed value. PUT will replace the entire item, and PATCH changing the specified field.
That’s it! But in reality, in my careers, we never used the PATCH method. The reason is that we still didn’t need it at that time. So I now live with this belief, and whenever I talk to others, they usually understand what I mean.
So, since I know about HTTP Method and REST. I only use these methods, GET, DELETE, POST, and PUT. I never have a chance (yet) to use PATCH.
We know clearly, how the PUT work. And I’ve been using PUT for a long time now. For example, I have this JSON. And I’m doing PUT operation.
GET /user/bxcodec
{
"name": "Iman",
"username": "bxcodec"
}
Applying HTTP PUT
PUT /user/bxcodec
{
"name": "Iman Tumorang",
"username": "bxcodec"
}
Final Results
GET /user/bxcodec
{
"name": "Iman Tumorang",
"username": "bxcodec"
}
And then, derived from PUT, then PATCH, from what people say, “PATCH not replacing the entire item, but only the specified one”
So, from that statement, in default, this is what I think how PATCH work. For example, I have this Request.
GET /user/bxcodec
{
"name": "Iman",
"username": "bxcodec"
}
Applying HTTP Patch
PATCH /user/bxcodec
{
"name": "Iman Tumorang"
}
Final Results
GET /user/bxcodec
{
"name": "Iman Tumorang",
"username": "bxcodec"
}
Right? This is how I think HTTP-PATCH should work. And I live with this belief for more than 3 years.
But, just now, when I write this, I found this on Golang docs here: https://golang.org/pkg/net/http/
Out of curiosity, I notice a different value there, I found a comment for
RFC 5789
. Why the heck it has a different RFC, not like the others? Why is it different?And, after looking at the RFC 5789, I found a weird thing. From the description,
With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.
So, from the RFC docs, it says, in the request body, I have to specify a set of actions or instructions to modify the current resource in request URI. As we can see in the example above. But how I do set the actions in the request body? How should I format it?
To answer the previous question, how should I format the action list in my request body? I found an interesting thing, it’s another RFC called JSON-Patch (RFC 6902). This is an RFC to explain how to use JSON-Patch for JSON operations.
A short example of how JSON-PATCH worked is more like this. For example, we have a JSON here.
{
"name": "Iman",
"username": "bxcodec"
}
Using the JSON-PATCH.
[
{ "op": "replace", "path": "/name", "value": "Iman Tumorang" },
{ "op": "add", "path": "/likes", "value": ["go", "blogging"] }
]
Patched results.
{
"name": "Iman Tumorang",
"username": "bxcodec",
"likes": [
"go",
"blogging"
]
}
So in JSON-PATCH, I have to define the operations, the path, and the value for modifying the resources. And all the available commands can be seen in the RFC6902.
So, here the plot twist, surprisingly, HTTP PATCH and JSON-PATCH have a correlation. When I open the RFC 6902, I got this.
JSON Patch is a format (identified by the media type “application/ json-patch+json”) for expressing a sequence of operations to apply to a target JSON document; it is suitable for use with the HTTP PATCH method.
Gotcha!
So, in simple, for HTTP-PATCH, we can use JSON-PATCH for the request body. So the action list for the request body, we can define it using JSON-PATCH.
So, to combine HTTP-PATCH and JSON-PATCH, if I put it into an example, it will be more like this below.
GET /user/bxcodec
{
"name": "Iman",
"username": "bxcodec"
}
Applying HTTP Patch
PATCH /user/bxcodec
[
{ "op": "replace", "path": "/name", "value": "Iman Tumorang" }
]
Final Results.
GET /user/bxcodec
{
"name": "Iman Tumorang",
"username": "bxcodec"
}
Today, after living with a wrong belief, I learned new things. HTTP-PATCH has a different way to implement it. We can use JSON-PATCH as the request-body on the HTTP-PATCH request method.
But, I don’t know, to be honest, I still feel this way is not really convenient. And it makes an extra layer of our implementations, compares to like what I used to be used.
Luckily, there’s already a lot of JSON-PATCH library out there, like https://github.com/evanphx/json-patch for Golang, https://www.npmjs.com/package/fast-json-patch in Typescript, and many more. So I don’t think it will be hard to implement it in my next projects. But yeah, let’s see haha.
But yeah, even it more convenient to change directly the value for patching (without using JSON-PATCH, and not following the RFC 5789) LOL, I will try to follow this in my next projects.