Writing REST APIs with Spring MVC and PATCH methods
A PATCH request updates selected fields of an existing resource without replacing the entire representation. This differs from PUT, which normally submits and replaces the complete resource. PATCH is useful for profile editors, subscription changes, address updates and other operations where sending every unchanged field would be wasteful or risky.
Spring MVC provides clean support for these partial updates through @PatchMapping, message converters and Jackson’s JSON patch utilities. The important design decision is choosing a payload format that clearly defines how missing fields, null values and nested properties should behave.
Why partial updates matter
REST APIs often expose resources containing fields controlled by separate systems or teams. A customer record might include profile details, loyalty points, marketing preferences and an internal risk score. Sending all of them during an update could overwrite newer values with stale client data.
A focused PATCH endpoint reduces accidental changes by accepting only the fields the caller intends to modify. It also produces smaller request bodies and makes authorisation easier to enforce. For example, a public customer profile endpoint can accept name and contact details while preventing updates to administrative fields such as account status or credit limits.
Mapping PATCH requests in Spring MVC
A controller can bind the request body to Jackson’s JsonNode and delegate the merge operation to a service layer:
@PatchMapping("/customers/{id}")
public ResponseEntity<CustomerDto> patchCustomer(
@PathVariable Long id,
@RequestBody JsonNode patch) {
CustomerDto updated = customerService.applyMergePatch(id, patch);
return ResponseEntity.ok(updated);
}
Clients should send Content-Type: application/merge-patch+json. The service should load the current resource, apply the patch, validate the resulting representation and save it atomically. It should never bind a request body directly to a persistence entity, because that can expose private fields and permit unauthorised changes.
- Use
@PatchMappingwith a resource identifier in the route. - Accept
application/merge-patch+jsonfor merge semantics. - Read the current representation before applying changes.
- Validate the merged result rather than only the incoming fields.
- Return the updated resource with an HTTP 200 response.
The Spring MVC tutorials also cover message conversion, controller design and service-layer patterns that complement this implementation.
Choosing a patch representation
JSON Merge Patch is convenient for flat updates because absent properties remain unchanged, while a null value removes a property. However, null cannot then be used to set a meaningful domain value to null. JSON Patch provides finer control through operations such as replace, add, remove, copy and move, including changes to array positions.
PUT remains appropriate when the client intentionally submits the complete resource. Whichever format is selected, the API documentation should define its behaviour, especially for nulls, arrays and unknown fields.
| Format | Example operation | Strongest use | Main caution |
|---|---|---|---|
| JSON Merge Patch | {"email": null} |
Simple optional-field updates | Null normally removes a field |
| JSON Patch | [{"op":"replace","path":"/email","value":"new@example.au"}] |
Precise nested or array changes | Operations require careful ordering |
| PUT | Complete resource representation | Full replacement | Higher risk of overwriting fields |
Preserving data and returning useful errors
Reliable partial updates depend on validation after the patch has been merged with the stored resource. Validating only the submitted fields can miss a combination that creates an invalid state, such as an updated international phone number paired with a restricted delivery suburb.
Concurrent edits also need attention. Optimistic locking with a version field can detect conflicting writes, while ETags and If-Match provide standards-based conditional updates. A failed precondition should return 412 Precondition Failed; conflicting application state may warrant 409 Conflict.
- Allowlist patchable fields before merging.
- Reject unknown or forbidden properties explicitly.
- Run bean validation on the final representation.
- Use transactions when related records change together.
- Translate validation failures into structured field-level errors.
Returning the updated representation helps clients confirm the result immediately. A 204 No Content response is also valid when the server has applied the change but does not need to return the resource.
Applying partial updates in Australian products
Australian applications often combine customer records with fulfilment information for Sydney, Melbourne and other regional markets. A PATCH operation can update a delivery address or contact number without altering the customer’s loyalty balance or the status of an order placed through an Australian marketplace.
Local business rules should remain explicit in the API. Prices can be stored as integer cents in AUD and returned with GST information, while customer interfaces may display dates in DD/MM/YYYY format even though the API uses ISO 8601. Australian Privacy Act obligations and the Australian Privacy Principles also favour collecting only necessary profile details and restricting changes to authorised fields.
The endpoint should support Australian postcodes, mobile number formats and address validation while keeping business rules in the service layer. This separation makes the REST API predictable for clients and gives Australian development teams a maintainable way to evolve customer, billing and delivery resources.