## What is JSON Patch?

JSON Patch is a standardized format defined in
[RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) for describing how to
modify a JSON document. It was created to address the need for a simple,
efficient, and standardized way to apply partial updates to resources,
especially over HTTP. Unlike other partial update formats, JSON Patch is
specifically designed to work with JSON documents, which are often used in
modern web APIs.

Initially, HTTP methods like `PUT` and `POST` were used to update resources.
However, this often resulted in sending large amounts of data over the network,
even when only a small part of the resource needed modification. The `PATCH`
method was introduced to allow for partial updates, but there was no
standardized format for the patch document. JSON Patch fills this gap by
providing a clear, concise way to express changes to a JSON document, helping to
reduce bandwidth, and improve the performance of web applications.

## How JSON Patch Works

JSON Patch operates on a JSON document as a sequence of atomic operations. An
operation is an object that describes a single change to the document. Each
operation includes an `op` field, which specifies the type of operation, and a
`path` field, which identifies the location in the document where the operation
should be applied.

Here's a basic structure of a JSON Patch:

Let's start with a simple JSON object.

```json
{
  "age": 29
}
```

```json
[
  { "op": "add", "path": "/name", "value": "Alice" },
  { "op": "replace", "path": "/age", "value": 30 }
]
```

In this example, the first operation adds a `name` field with the value `Alice`
to the root of the document, and the second operation replaces the existing
`age` field with a new value.

The resulting JSON

```json
{
  "name": "Alice",
  "age": 30
}
```

JSON Patch allows the following operations:

- **Add** a value to an object/array
- **Remove** a value from an object or array
- **Replace** a value (essentially Remove + Add)
- **Copy** a value from one location to another
- **Move** a value from one location to another (essentially a Copy + Remove)
- **Test** if a value is set at a particular path in the JSON document

## JSON Pointer

In the example above, you might have been confused by how we determined the
`path` to use. JSON Patch relies on another standard called
[JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) to define the path
to the part of the JSON document being modified. A JSON Pointer is a string of
tokens separated by slashes (`/`), with each token identifying a level in the
document's hierarchy.

Here's an example JSON document and corresponding JSON Pointer:

JSON Document:

```json
{
  "user": {
    "name": "Bob",
    "age": 25,
    "friends": ["Alice", "John"]
  }
}
```

JSON Pointer: `/user/name`

This pointer identifies the `name` field within the `user` object. You can refer
to an array's entries by their index (ex. `/user/friends/0` is Alice). The last
element in an array ca be referenced using `-` (ex. `/user/friends/-` is John).
If a property name contains `~`, then inside the pointer it must be escaped
using `~0`, or if contains `/` then it must be escaped using `~1`.

For more examples go to the
[JSON Pointer specification page](https://datatracker.ietf.org/doc/html/rfc6901)
or [this helpful guide](https://opis.io/json-schema/2.x/pointers.html).

## Strengths and Weaknesses of JSON Patch

While JSON Patch is a flexible and powerful standard, it is not free of
pitfalls. Lets dive into the strengths and weaknesses of the JSON Patch format.

### Strengths

1. **Precision**: JSON Patch allows for precise modifications of a JSON
   document. This means you can target specific elements in a complex structure
   without affecting other parts of the document.

2. **Efficiency**: Unlike sending the entire updated document, JSON Patch only
   sends the changes. This minimizes data transmission and latency between
   clients and servers.

3. **Atomicity**: If a JSON Patch operation fails, the entire operation can be
   rolled back. This ensures data integrity and prevents partial updates.

4. **Idempotency**: JSON Patch operations can be safely retried without causing
   unintended side effects. This is crucial for reliable distributed systems and
   APIs.

5. **Complex Operations**: JSON Patch supports intricate operations, such as
   moving an element from one location to another within the same document. You
   can also copy elements from one place and paste them elsewhere.

6. **Validation**: APIs using JSON Patch can validate incoming patches to ensure
   they conform to expected operations and structure, reducing the likelihood of
   malformed requests.

7. **Standards-Based**: JSON Patch is based on web standards, making it easier
   to integrate with a wide range of clients and servers.

8. **Field-level Access Control**: Despite being complex to implement, JSON
   Patch provides the possibility to restrict modifications at a granular level,
   ensuring only authorized changes are made.

9. **Batch Operations**: Multiple changes can be bundled into a single JSON
   Patch, efficiently handling concurrent updates in a single request. If you
   are making calls to an external API that is rate limited, but supports JSON
   Patch, you can concatenate all of your patches together at the API gateway
   level and fire off a single request rather than multiple.

#### Optimized for Updates

JSON 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/json-patch+json

[
  {
    "op": "replace",
    "path": "/id",
    "value": "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",
  "state": "California",
  "city": "Redwood City",
  "zip": "94063"
}
```

Notice how much smaller the first request is?

### Weaknesses

1. **Complexity**: JSON Patch can be intricate, especially when dealing with
   complex JSON structures. This typically requires developers to rely on an
   external library to handle to parsing and application of JSON Patches, which
   can also introduce security and maintenance issues.

2. **Maintenance Costs**: As APIs evolve, the paths specified in JSON Patches
   might become obsolete, leading to maintenance overhead.

3. **Debugging Difficulty**: Tracing changes in JSON Patch can be challenging,
   especially if multiple operations are batched together. Sending over the
   entire object with a POST gives you a snapshot through the request body,
   where as a PATCH requires you to have knowledge of the state of the JSON
   document before it was applied

4. **Preservation of Object Order**: JSON Patch's move operations don't
   guarantee the order of objects, which might necessitate supplementary
   operations to reorganize elements.

5. **Security Concerns**: Improper handling of JSON Patch requests can open up
   vulnerabilities. For example, if an API doesn't properly validate a move or
   remove operation, it could result in unintended data loss or exposure.

## JSON Patch Operations with Examples

Below are examples of each JSON Patch operation, alongside the resulting JSON.
Let's start with the following document:

```json
{
  "user": {
    "name": "Bob",
    "age": 25
  }
}
```

1. **Add**

   JSON Patch:

   ```json
   { "op": "add", "path": "/email", "value": "bob@example.com" }
   ```

   After:

   ```json
   {
     "user": {
       "name": "Bob",
       "age": 25
     },
     "email": "bob@example.com"
   }
   ```

2. **Remove**

   JSON Patch:

   ```json
   { "op": "remove", "path": "/user/age" }
   ```

   After:

   ```json
   {
     "user": {
       "name": "Bob"
     }
   }
   ```

3. **Replace**

   JSON Patch:

   ```json
   { "op": "replace", "path": "/user/name", "value": "Alice" }
   ```

   After:

   ```json
   {
     "user": {
       "name": "Alice",
       "age": 25
     }
   }
   ```

4. **Move**

   JSON Patch:

   ```json
   { "op": "move", "from": "/user/age", "path": "/user/birthYear" }
   ```

   After:

   ```json
   {
     "user": {
       "name": "Alice",
       "birthYear": 25
     }
   }
   ```

5. **Copy**

   JSON Patch:

   ```json
   { "op": "copy", "from": "/user/name", "path": "/displayName" }
   ```

   After:

   ```json
   {
     "user": {
       "name": "Alice",
       "birthYear": 25
     },
     "displayName": "Alice"
   }
   ```

6. **Test**

   JSON Patch:

   ```json
   { "op": "test", "path": "/displayName", "value": "Alice" }
   ```

   If the test operation succeeds, it has no effect on the document. If it
   fails, the entire patch is considered unsuccessful.

## JSON Patch in Tools and Libraries

JSON Patch is widely used in API development and is supported by various
libraries in different programming languages. Here are some examples:

### Libraries

- [fast-json-patch](https://www.npmjs.com/package/fast-json-patch): A Javascript
  node JS package for generating and applying JSON patches.

- [python-json-patch](https://github.com/stefankoegl/python-json-patch): Library
  to apply JSON Patches in Python.

- [JsonPatch library in .NET](https://learn.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-7.0):
  A C# implementation of JSON Patch.

If you use a different languauge, here's a more
[complete list of libraries](https://github.com/dharmafly/jsonpatch.com/blob/gh-pages/index.md#libraries).

### Tools

A great tool for learning JSON Patch is [jsonpatch.me](https://jsonpatch.me/) -
a free online service for running JSON Patch commands. It even has an API!

## Generating a JSON Patch Change Set in 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. To generate a JSON Patch change
set, a library like `fast-json-patch` can be used. Here's a simple example:

```typescript
import * as jsonpatch from "fast-json-patch";

const originalDoc = {
  firstName: "Albert",
  contactDetails: { phoneNumbers: [] },
};
const modifiedDoc = {
  firstName: "Joachim",
  contactDetails: { phoneNumbers: [] },
};

// Generate the JSON Patch
const patch = jsonpatch.compare(originalDoc, modifiedDoc);

console.log(patch);

// 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/json-patch+json",
});
await fetch("https://your-backend.com/foo", { method: "PATCH", headers });
```

This code outputs the necessary patch document to convert the original document
into the modified document:

```json
[{ "op": "replace", "path": "/firstName", "value": "Joachim" }]
```

## Handling HTTP PATCH Requests with JSON Patch in NodeJS

To handle a PATCH request that includes a JSON Patch document, the
`fast-json-patch` library can be used again. Here's an example using express as
your server framework:

```typescript
const express = require("express");
const { applyPatch } = require("fast-json-patch");
const bodyParser = require("body-parser");

const app = express();
app.use(bodyParser.json());

let document = { firstName: "Albert", contactDetails: { phoneNumbers: [] } };

app.patch("/", (req, res) => {
  try {
    document = applyPatch(document, req.body);
    res.status(200).json(document);
  } catch (error) {
    res.status(400).send("Invalid JSON Patch document");
  }
});

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

This server listens for PATCH requests and applies the provided JSON Patch
document to an existing resource.

## Validating JSON Patch Request Bodies

As mentioned in the risks of JSON patch, a malformed or malicious request body
sent to your API can cause data loss or other unintended consequences. That's
why its important to [validate the request body](/blog/verify-json-schema). It's
typically best to validate the request body using an API Gateway (ex. Zuplo) so
the validation can be applied consistently across all of your Patch endpoints,
and be executed in a faster runtime. Here's three ways to do it:

### Traditional: Using AJV + JSON Schema

To simply validate a JSON Patch request body, the [AJV](https://ajv.js.org/)
library and a JSON schema can be used:

```typescript
const Ajv = require("ajv");
const schema = require("json.schemastore.org/json-patch");

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

const patch = [{ op: "replace", path: "/firstName", value: "Joachim" }];

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

This code validates a JSON Patch document against a JSON schema and prints
`Valid Patch` if the document is valid. This does not ensure sensitive data
isn't tampered with.

### Simpler: Using Zuplo + OpenAPI

A simpler way of implementing the same validation as above is by adding the
[JSON Schema for JSON Patch](https://json.schemastore.org/json-patch) directly
into your OpenAPI file in your Zuplo API Gateway. Then you can add the
[Request Validation policy](/docs/policies/request-validation-inbound) directly
to all of your PATCH endpoints. The policy will 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" />

### Advanced: Using `fast-json-patch`

We can actually reuse the `fast-json-patch` library in our API to validate the
request body, and even add additional `test` operations within the patch to
ensure certain invariants aren't violated.

```typescript
import * as fastJsonPatch from "fast-json-patch";

const patch = [{ op: "replace", path: "/firstName", value: "Joachim" }];

// Add invariants to safeguard the firstName property
patch.push({
  op: "test",
  path: "/firstName",
  value: originalDocument.firstName,
});
const errors = fastJsonPatch.validate(patch, originalDocument);

if (errors === undefined) {
  // there are no errors!
} else {
  console.log(`Error ${errors.name}: ${errors.message}`);
  console.log("at", errors[0].operation); // ex. {op: 'replace', path: '/firstName', value: 'Joachim'}
}
```

The above code can be run within a
[Custom Code Inbound Policy](/docs/policies/custom-code-inbound) in Zuplo and
easily applied to all of your Patch endpoints.

## Alternatives to JSON Patch

[JSON Merge Patch](/learning-center/what-is-json-merge-patch) is a recently
proposed alternative to JSON Patch that seeks to simplify the interface for
specifying changes. Check out our
[JSON Patch vs JSON Merge Patch comparison](/learning-center/json-patch-vs-json-merge-patch)
to learn more.

## Building Efficient Application Programming Interfaces with JSON Patch

JSON 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 Patch
across your APIs or just want to modernize your APIs more generally, and want
advice from an API expert - [get in touch](https://?utm_source=blog).