When to Use PUT and When to Use PATCH

Article summary

As I’ve progressed in learning about backend API, I’ve noticed that, across projects, PATCH is infrequently utilized. Sometimes, it just doesn’t make sense. Often, the business logic doesn’t line up with what you’re trying to do. So when exactly do you use PATCH?

When

In simple terms, if you intend to update every attribute on an object — use PUT. Otherwise, use PATCH. This is the way these two are by design. You basically have to send over the entire object whenever a PUT is used. Look at your code again now. Are you really using PUT the way it’s intended?

I think many developers shy away from anything that looks unfamiliar because it can look scary at first. I mean, the request body for PATCH certainly looks very different from any else you use in a typical web app. You might not always be able to do the swap for some non-technical reason, but it’s a good tool to have on your belt regardless.

Why

Ultimately, whether you use PUT or PATCH is up to you. I would argue that it’s a little safer and maybe a little faster if you have an app that’s constantly updating objects. It’s safer because you’re not sending the entire object every time. It’s also faster because you don’t need to validate the entire object all over again or worry about any other attribute mapping over correctly if you’re not changing it.

How?!

So how DO we utilize this new tool? Implementation is easy enough. Instead, it’s usually the request body that confuses people (me).

Let’s go over some basics. You can send over a JSON array oftentimes with this standard format:


[
  {
    "op": "operation_name",
    "path": "path_to_attribute",
    "value": "new_value"
  }
]

Here the “op” is a string dictating the type of operation to occur. The “path” is the path to the object’s attribute that needs to be changed. The “value” is the new value that will be updated. If you notice this is also a JSON array of objects. This means you can send over multiple changes in the same request to very specific attributes if you want very easily.

So what exactly is “op”? The operation can be any of these: “add”, “remove”, “replace”, “move”, “copy”, or “test.” Honestly, I mostly have made use of “replace” to update values and “test” — so I’ll mostly be talking about these. The “test” operator is useful if you aren’t sure if the path or value you want to change is correct. It’s a good safeguard if you want to validate before making any changes.

So — how do I update an object’s attribute value? Let’s use this simple object as an example:


{
  “first_name”: “John”,
  “last_name”: “Smith”,
  “contact_info”:
  {
    "email”: “[email protected]”,
    "phone_number”: “(111) 111-1111
  },
  “list_of_things”:
  [
    { “id”: 1, “name”: “item_1”, "location": "Detroit, MI" },
    { “id”: 2, “name”: “item_2”, "location": "Ann Arbor, MI" }
  ]
}

Now let’s update some values! Here’s an example:


[
  { "op": "replace", "path": "/first_name", "value": "Jane" },
  { "op": "replace", "path": "/last_name", "value": "Doe" },
  { "op": "replace", "path": "/contact_info/email", "value": "[email protected]" }
]

That’s simple enough, right? But what about changing a list of objects? The first thing we need to include is a unique identifier for the item in the list. The second is that we need to understand more about how “replace” works here. We are giving a path to an array. We are giving it a value to replace that array with. If we only include one item, then our list of two items after the PATCH will shrink down to just one. Here’s an example:


[
  {
    "op": "replace",
    "path": "/list_of_things",
    "value": [ { “id”: 1, “name”: “updated_item_1” } ]
  }
]

If we run this code, the “location” for an item with “id” 1 will be null. Also, the item with “id” 2 will be… you guessed it, null (removed from the list). This is because we replaced it with… nothing.

That is, be more thoughtful when updating lists.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *