---
title: "What is JSON Merge Patch?"
description: "JSON Merge Patch is an HTTP PATCH request body format that describes modifications to a target JSON. It's a simpler alternative to JSON Patch."
canonicalUrl: "https://zuplo.com/learning-center/what-is-json-merge-patch"
pageType: "learning-center"
authors: "adrian"
tags: "API Best Practices, Tutorial"
image: "https://zuplo.com/og?text=Unlocking%20the%20Power%20of%20JSON%20Merge%20Patch"
---
JSON Merge Patch is a format defined in
[RFC 7386](https://datatracker.ietf.org/doc/html/rfc7386), designed for use with
the HTTP PATCH method to describe modifications to a target JSON document. It
offers a simpler alternative to
[JSON Patch](/learning-center/unlocking-the-power-of-json-patch) (RFC 6902) for
updating JSON resources, especially when updates are object-based and don't
require explicit null values or complicated array operations.

## History and Use in API Development

Standardized in October 2014, JSON Merge Patch emerged as a more straightforward
method for partial resource updates compared to JSON Patch. While JSON Patch
uses a list of operations (for example, add, remove, replace), JSON Merge Patch
uses a patch document that mirrors the target document's structure. This makes
it more human-readable and easier for simple updates. Here's an example of
adding a new property to a JSON object

```json
Original Document:
{
  "name": "James Bond",
  "age": 45
}

Patch Document:
{
  "superpower": "Charm"
}

Resulting Document:
{
  "name": "James Bond",
  "age": 45,
  "superpower": "Charm"
}
```

In API development, JSON Merge Patch is often preferred for straightforward
updates that don't involve complicated operations like adding or removing array
elements individually. It's particularly useful when only a subset of a
resource's properties need updating, avoiding the need to send the entire
resource or a list of operations.

## How JSON Merge Patch Works

JSON Merge Patch merges the patch document's contents with the target JSON
document. Here's how it works:

1. If the patch isn't a JSON object, it replaces the entire target document.
2. If the patch is an object, it merges with the target object. For each member
   in the patch:
   - If the value is null, the corresponding member in the target is removed.
   - If the member doesn't exist in the target, it's added.
   - If the member exists, its value is replaced with the patch's value.

> If you'd like to test out JSON Merge Patch for yourself, check out our new
> [JSON Merge Patch tool and API](https://www.jsonmergepatch.com/).

## Strengths and Weaknesses

### Strengths

- **Simplicity**: Easier to read and write compared to JSON Patch.
- **Human Readability**: Intuitive for developers to understand what is changing
  at a glance.

#### Optimized for Updates

JSON Merge Patch only transmits the changes needed, minimizing payload size.
This makes it more efficient than sending entire JSON objects, reducing response
times and bandwidth.

```json
HTTP/1.1 PATCH
Content-Type: application/merge-patch+json

{
  "id": "123456"
}
```

vs

```json
HTTP/1.1 POST
Content-Type: application/json

{
  "id": "123456",
  "firstName": "John",
  "lastName": "Doe",
  "fullName": "John Doe",
  "age": 21,
  "country": "United States",
}
```

Notice how much smaller the first request is?

### Weaknesses

- **Limited Array Operations**: Can't add, remove, or change array elements
  individually; can only replace the entire array.
- **No Recursive Behavior for Non-Objects**: Doesn't support recursive
  operations for non-object patches.
- **Null Values**: Null values in the patch remove the corresponding field in
  the target document, and setting a field to null isn't possible if it doesn't
  exist in the target.

## Examples of JSON Merge Patch Operations

### Adding a New Field

Original Document:

```json
{ "name": "James Bond", "age": 45 }
```

Patch Document:

```json
{ "nickname": "007" }
```

Resulting Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "nickname": "007"
}
```

### Replacing a Field

Original Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "nickname": "007"
}
```

Patch Document:

```json
{ "nickname": "008" }
```

Resulting Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "nickname": "008"
}
```

### Removing a field

Original Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "nickname": "007"
}
```

Patch Document:

```json
{ "nickname": null }
```

Resulting Document:

```json
{ "name": "James Bond", "age": 45 }
```

### Replacing an Array

Original Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "movies": ["Dr. No", "From Russia With Love"]
}
```

Patch Document:

```json
{ "movies": ["Goldfinger", "Thunderball"] }
```

Resulting Document:

```json
{
  "name": "James Bond",
  "age": 45,
  "movies": ["Goldfinger", "Thunderball"]
}
```

## Tools and Libraries Using JSON Merge Patch

Several tools and libraries implement the JSON Merge Patch standard:

- **jsonmergepatch.com ([Web](https://www.jsonmergepatch.com/) and
  [API](https://api.jsonmergepatch.com/docs/routes/index))**: Free tool that
  lets you generate JSON Merge Patches from two JSON objects, or apply a JSON
  Merge Patch on a JSON object.
- **json-merge-patch ([NPM](https://www.npmjs.com/package/json-merge-patch))**:
  Provides functions to apply and generate JSON Merge Patches. Install with
  `npm install json-merge-patch`.
- **json-merge-patch
  ([Python](https://github.com/OpenDataServices/json-merge-patch))**: Implements
  JSON Merge Patch for Python. Install with `pip install json-merge-patch`.

## Generating JSON Merge Patch Changeset in Client-Side TypeScript

If you are working on a client (ex. a React form), you will want to generate a
changeset client-side and send it to your API. Use the `json-merge-patch`
library to generate a JSON Merge Patch changeset in TypeScript:

```typescript
import jsonMergePatch from "json-merge-patch";

// Original JSON object
const source = {
  title: "Goodbye!",
  author: {
    givenName: "John",
    familyName: "Doe",
  },
};

// Target JSON object
const target = {
  title: "Hello!",
  author: {
    familyName: null,
  },
};

// Generate the patch
const patch = jsonMergePatch.generate(source, target);

console.log(patch);
// Output:
// {
//   "title": "Hello!",
//   "author": {
//     "familyName": null
//   }
// }

// Send the patch to the server
const headers = new Headers({
  // This content-type is specified in the spec
  // and is useful for the server to validate
  "content-type": "application/merge-patch+json",
});
await fetch("https://your-backend.com/foo", { method: "PATCH", headers });
```

This code generates a patch that transforms the `source` object into the
`target` object.

## Handling HTTP Patch Request in Node.js

To handle an HTTP PATCH request in Node.js using JSON Merge Patch, parse the
request body and apply the patch to the target JSON object. Here's an example
using Express.js:

```typescript
const express = require("express");
const jsonMergePatch = require("json-merge-patch");
const app = express();
app.use(express.json());

app.patch("/resource", (req, res) => {
  // Assuming you have the original resource stored somewhere
  const originalResource = {
    title: "Goodbye!",
    author: {
      givenName: "John",
      familyName: "Doe",
    },
  };

  // Apply the patch to the original resource
  const patchedResource = jsonMergePatch.apply(originalResource, req.body);

  // Save the patched resource (e.g., to a database)
  // For demonstration purposes, just log it
  console.log(patchedResource);

  res.status(200).send(patchedResource);
});

app.listen(3000, () => {
  console.log("Server listening on port 3000");
});
```

In this example, the `express.json()` middleware parses the JSON body of the
PATCH request, and the `jsonMergePatch.apply` function applies the patch to the
original resource.

## Validating a JSON Merge Patch Request Body

To validate a JSON Merge Patch request body, ensure it conforms to the JSON
Merge Patch format. Key points to check include:

1. **Content Type**: Ensure the `Content-Type` header is set to
   `application/merge-patch+json`.
2. **JSON Object**: The request body should be a valid JSON object.
3. **Patch Structure**: The patch should only contain the changes, and any
   missing properties in the patch will be retained from the original object.
4. **Property-Level Security**: Malicious callers might try and delete essential
   properties or modify data they are not supposed to using a JSON Merge Patch -
   making it critical to check which properties changed

Here's three ways of validating a JSON Merge Patch request body using Node.js:

### Manual: Maintain a list of protected `json-pointer` properties

Using this approach, we maintain a list of JSON Pointers to properties we want
to protect. Then, using lodash, we check if the properties have been modifed.
Here's a complete code sample:

```typescript
const _ = require("lodash");
const pointer = require("json-pointer");
const jsonMergePatch = require("json-merge-patch");

app.patch("/resource", (req, res) => {
  if (req.headers["content-type"] !== "application/merge-patch+json") {
    return res.status(415).send("Unsupported Media Type");
  }

  try {
    const patch = req.body;
    if (typeof patch !== "object" || Array.isArray(patch)) {
      return res.status(400).send("Invalid JSON Merge Patch");
    }

    // Apply the patch (as shown in the previous example)
    const originalResource = {
      title: "Goodbye!",
      author: {
        givenName: "John",
        familyName: "Doe",
      },
    };
    const patchedResource = jsonMergePatch.apply(originalResource, patch);

    // Validate protected properties are untouched
    const protectedPropertyPointers = ["/author/familyName"];
    for (const protectedPropertyPointer of protectedPropertyPointers) {
      const originalValue = pointer.get(
        originalResource,
        protectedPropertyPointer,
      );
      const newValue = pointer.get(patchedResource, protectedPropertyPointer);
      // Compare with lodash
      if (!_.isEqual(oldValue, newValue)) {
        res
          .status(400)
          .send(
            `Invalid JSON Merge Patch. Property ${protectedPropertyPointer} cannot be modified`,
          );
      }
    }

    // Save the patched resource (e.g., to a database)
    // For demonstration purposes, just log it
    console.log(patchedResource);

    res.status(204).send(patchedResource);
  } catch (error) {
    console.error(error);
    res.status(400).send("Invalid JSON Merge Patch");
  }
});
```

### Faster: Use JSON Schema + AJV

If your JSON object is schematized, you can also apply
[JSON Schema validation](/blog/verify-json-schema) with a modified schema. The
modifications needed are as follows:

1. Remove all 'protected' properties to ensure they are not passed through the
   request body. Also set `additionalProperties` to `false` to avoid them being
   passed in anyways.
2. Remove `required` from objects, all properties are now optional since you
   don't include properties you aren't modifying in JSON Merge Patch
3. Allow `null` as a type on any property that can be deleted. Ex.
   `{"type": "number}` would become `{"type": ["number", "null"]}`

Once your schema is ready, the [AJV](https://ajv.js.org/) library can be used to
apply it:

```typescript
const Ajv = require("ajv");
const schema = require("your-modified-schema.json");

const ajv = new Ajv();
const validate = ajv.compile(schema);

const patch = { id: 1234 };

if (validate(patch)) {
  console.log("Valid Patch");
} else {
  console.log("Invalid Patch", validate.errors);
  // Return a 400 error
}
```

### Fastest + Simplest: Use Zuplo + OpenAPI

Zuplo already supports JSON Schema validation through its
[Request Validation policy](/docs/policies/request-validation-inbound). Simply
add the modified schema from the step above to your OpenAPI documentation for
your PATCH endpoints and the policy will start validating requests. The policy
will also automatically return an HTTP 400 error using the
[Problem Details format](/learning-center/the-power-of-problem-details). Here's
a
[step-by-step guide](/blog/adding-dev-portal-and-request-validation-firebase#step-5-adding-request-validation)
if you're unfamiliar with Zuplo. Side-benefit is that you now have a fully
documented OpenAPI file, complete with schemas. Here's a quick tutorial on the
concept:

<YouTubeVideo videoId="POkuwh0iAbc" />

## Building Efficient Application Programming Interfaces with JSON Merge Patch

JSON Merge Patch is a powerful and efficient way to perform partial updates on
JSON documents. By understanding how it works and how to implement it,
developers can build more efficient APIs and applications that send less data
over the network and process updates more quickly. If you're looking to
implement JSON Merge Patch across your APIs or just want to modernize your APIs
more generally, and want advice from an API expert -
[get in touch](https://zuplo.com/meeting?utm_source=blog).