Backend Development 9 min read

Mastering HTTP PATCH with JSON Patch in Spring Boot 3.2.5

This tutorial explains how to perform partial updates of RESTful resources using the HTTP PATCH method and JSON Patch format in Spring Boot 3.2.5, covering all RFC‑6902 operations with code examples and a complete working controller implementation.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering HTTP PATCH with JSON Patch in Spring Boot 3.2.5

1. Introduction

HTTP PATCH enables partial updates of HTTP resources. This article demonstrates how to use the PATCH method together with the JSON Patch document format to modify RESTful resources in a Spring Boot 3.2.5 application.

2. JSON Patch Operations

2.1 add

Adds a new value to an object or inserts a value into an array at a specified index.

<code>{
  "op": "add",
  "path": "/favorites/0",
  "value": "Bread"
}</code>

Result:

<code>{
  "id": "1",
  "telephone": "001-555-1234",
  "favorites": ["Bread","Milk","Eggs"],
  "communicationPreferences": {"post":true,"email":true}
}</code>

2.2 remove

Removes a property or an array element.

<code>{
  "op": "remove",
  "path": "/communicationPreferences"
}</code>

Result:

<code>{
  "id": "1",
  "telephone": "001-555-1234",
  "favorites": ["Bread","Milk","Eggs"],
  "communicationPreferences": null
}</code>

2.3 replace

Replaces the value at the target location with a new value.

<code>{
  "op": "replace",
  "path": "/telephone",
  "value": "001-555-5678"
}</code>

Result:

<code>{
  "id": "1",
  "telephone": "001-555-5678",
  "favorites": ["Bread","Milk","Eggs"],
  "communicationPreferences": null
}</code>

2.4 move

Moves a value from one location to another.

<code>{
  "op": "move",
  "from": "/favorites/0",
  "path": "/favorites/-"
}</code>

Result:

<code>{
  "id": "1",
  "telephone": "001-555-5678",
  "favorites": ["Milk","Eggs","Bread"],
  "communicationPreferences": null
}</code>

2.5 copy

Copies a value from a source location to a target location.

<code>{
  "op": "copy",
  "from": "/favorites/0",
  "path": "/favorites/-"
}</code>

Result:

<code>{
  "id": "1",
  "telephone": "001-555-5678",
  "favorites": ["Milk","Eggs","Bread","Milk"],
  "communicationPreferences": null
}</code>

2.6 test

Tests whether a value at the given path matches the supplied value.

<code>{
  "op": "test",
  "path": "/telephone",
  "value": "001-555-5678"
}</code>

The request must use the content type application/json-patch+json .

3. Practical Example

3.1 Add Dependency

<code>&lt;dependency&gt;
  &lt;groupId&gt;com.github.java-json-tools&lt;/groupId&gt;
  &lt;artifactId&gt;json-patch&lt;/artifactId&gt;
  &lt;version&gt;1.13&lt;/version&gt;
&lt;/dependency&gt;</code>

3.2 Define Entity

<code>public class Customer {
  private Long id;
  private String telephone;
  private List<String> favorites;
  private Map<String, Boolean> communicationPreferences;
  // constructors, getters, setters omitted for brevity
}</code>

3.3 Define Exception

<code>public static class CustomerNotFoundException extends RuntimeException {}</code>

3.4 Service Layer

<code>@Service
public class CustomerService {
  private static final List<Customer> DATAS = List.of(
    new Customer(1L, "188", List.of("Milk","Eggs"), Map.of("phone",true,"email",true))
  );
  public Optional<Customer> findCustomer(Long id) {
    return DATAS.stream().filter(c -> c.getId() == id).findFirst();
  }
}</code>

3.5 Controller

<code>@PatchMapping(path="/{id}", consumes="application/json-patch+json")
public ResponseEntity<Customer> updateCustomer(@PathVariable Long id, @RequestBody JsonPatch patch) {
  try {
    Customer customer = customerService.findCustomer(id).orElseThrow(CustomerNotFoundException::new);
    Customer patched = applyPatchToCustomer(patch, customer);
    return ResponseEntity.ok(patched);
  } catch (JsonPatchException | JsonProcessingException e) {
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  } catch (CustomerNotFoundException e) {
    return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
  }
}

private Customer applyPatchToCustomer(JsonPatch patch, Customer target) throws JsonPatchException, JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  JsonNode patched = patch.apply(mapper.convertValue(target, JsonNode.class));
  return mapper.treeToValue(patched, Customer.class);
}</code>

Key points: the controller consumes application/json-patch+json and receives the request body as a JsonPatch object.

3.6 Test Request

The following request body contains two operations (replace and add) and returns the updated customer when executed.

After sending the request, the response shows the successful modification of the resource.

Feel free to modify the JSON Patch body to perform any other supported operation.

JavaBackend DevelopmentSpring BootREST APIHTTP PATCHJSON Patch
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.