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.
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><dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-patch</artifactId>
<version>1.13</version>
</dependency></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.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.