Spring MVC PATCH method: partial updates

http method patch is used to in spring boot
http patch request example java
http patch method vulnerability
rest patch best practices
http patch vs put
spring data jpa partial update
json patch
express patch example

I have a project where I am using Spring MVC + Jackson to build a REST service. Let's say I have the following java entity

public class MyEntity {
    private Integer id;
    private boolean aBoolean;
    private String aVeryBigString;
    //getter & setters
}

Sometimes, I just want to update the boolean value, and I don't think that sending the whole object with its big string is a good idea just to update a simple boolean. So, I have considered using the PATCH HTTP method to only send the fields that need to be updated. So, I declare the following method in my controller:

@RequestMapping(method = RequestMethod.PATCH)
public void patch(@RequestBody MyVariable myVariable) {
    //calling a service to update the entity
}

The problem is: how do I know which fields need to be updated? For instance, if the client just wants to update the boolean, I will get an object with an empty "aVeryBigString". How am I supposed to know that the user just wants to update the boolean, but does not want to empty the string?

I have "solved" the problem by building custom URLs. For instance, the following URL: POST /myentities/1/aboolean/true will be mapped to a method that allows to only update the boolean. The problem with this solution is that it is not REST compliant. I don't want to be 100% REST compliant, but I do not feel comfortable with providing a custom URL to update each field (especially given that it causes problems when I want to update several fields).

Another solution would be to split "MyEntity" into multiple resources and just update these resources, but I feel like it does not make sense: "MyEntity" is a plain resource, it is not composed of other resources.

So, is there an elegant way of solving this problem?

You may change boolean to Boolean and assign null value for all fields that you don't want to update. The only one not null value will define you which field client want to update.

HTTP PUT vs HTTP PATCH in a REST API, Learn about the difference between PUT and PATCH HTTP methods, and their implications when building your Spring API. When they're doing a partial update, they can use HTTP PATCH. We implemented a simple Spring REST controller to update a Resource via PUT method and a partial update  Using plain JSON together with PATCH method is against HTTP PATCH specification. – botchniaque Aug 20 '14 at 12:55 Spring does/can not use PATCH to patch your object because of the same problem you already have: The JSON deserializer creates an Java POJO with nulled fields.

This could be very late, but for the sake of newbies and people who encounter the same problem, let me share you my own solution.

In my past projects, to make it simple, I just use the native java Map. It will capture all the new values including the null values that the client explicitly set to null. At this point, it will be easy to determine which java properties needs to be set as null, unlike when you use the same POJO as your domain model, you won't be able to distinguish which fields are set by the client to null and which are just not included in the update but by default will be null.

In addition, you have to require the http request to send the ID of the record you want to update, and do not include it on the patch data structure. What I did, is set the ID in the URL as path variable, and the patch data as a PATCH body.Then with the ID, you would get first the record via a domain model,then with the HashMap, you can just use a mapper service or utility to patch the changes to the concerned domain model.

Update

You can create a abstract superclass for your services with this kind of generic code, you must use Java Generics. This is just a segment of possible implementation, I hope you get the idea.Also it is better to use mapper framework such as Orika or Dozer.

public abstract class AbstractService<Entity extends BaseEntity, DTO extends BaseDto> {
    @Autowired
    private MapperService mapper;

    @Autowired
    private BaseRepo<Entity> repo;

    private Class<DTO> dtoClass;

    private Class<Entity> entityCLass;

    public AbstractService(){
       entityCLass = (Class<Entity>) SomeReflectionTool.getGenericParameter()[0];
       dtoClass = (Class<DTO>) SomeReflectionTool.getGenericParameter()[1];
    }

    public DTO patch(Long id, Map<String, Object> patchValues) {
        Entity entity = repo.get(id);
        DTO dto = mapper.map(entity, dtoClass);
        mapper.map(patchValues, dto);
        Entity updatedEntity = toEntity(dto);
        save(updatedEntity);
        return dto;
    }
}

Using JSON Patch in Spring REST APIs, I just announced the new Learn Spring course, focused on the The HTTP PATCH method offers a nice way to apply partial updates to resources. As a result, our controller method will receive the request body as a  If you map to your value bean using @RequestBody, you'll have to figure what is actually set and what null values mean. Others options would be limit PATCH requests to one property and specify it in url or map the values to a Map. See also Spring MVC PATCH method: partial updates.

The correct way to do this is the way proposed in JSON PATCH RFC 6902

A request example would be:

PATCH http://example.com/api/entity/1 HTTP/1.1
Content-Type: application/json-patch+json 

[
  { "op": "replace", "path": "aBoolean", "value": true }
]

Using HTTP PATCH in Spring, Spring Integration Tutorials · Spring MVC Tutorials · Spring Security Tutorials Yes, in the essence the semantics of the PATCH method in the context of the HTTP-based REST(ful) web services is partial update of the resource. this simple JAX-RS 2.1 web API into the beautiful Spring Boot envelope. The HTTP verb named PATCH can be used for partial updates, i.e., when you would like to update just a few fields of a resource. While you could update a resource “partially” using HTTP PUT, by

After digging around a bit I found an acceptable solution using the same approach currently used by a Spring MVC DomainObjectReader see also: JsonPatchHandler

@RepositoryRestController
public class BookCustomRepository {
    private final DomainObjectReader domainObjectReader;
    private final ObjectMapper mapper;

    private final BookRepository repository;


    @Autowired
    public BookCustomRepository(BookRepository bookRepository, 
                                ObjectMapper mapper,
                                PersistentEntities persistentEntities,
                                Associations associationLinks) {
        this.repository = bookRepository;
        this.mapper = mapper;
        this.domainObjectReader = new DomainObjectReader(persistentEntities, associationLinks);
    }


    @PatchMapping(value = "/book/{id}", consumes = {MediaType.APPLICATION_JSON_UTF8_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<?> patch(@PathVariable String id, ServletServerHttpRequest request) throws IOException {

        Book entityToPatch = repository.findById(id).orElseThrow(ResourceNotFoundException::new);
        Book patched = domainObjectReader.read(request.getBody(), entityToPatch, mapper);
        repository.save(patched);

        return ResponseEntity.noContent().build();
    }

}

Run away from 'null' checks feast: doing PATCH properly with JSON , The HTTP verb named PATCH can be used for partial updates, i.e., when You should use the PUT method only when you would like to replace the resource in its entirety. ASP.NET Web API incorporates nice support for HTTP PATCH In the new project you have created, create a controller named  This example shows how to handle HTTP PATCH request in Spring MVC. PUT vs PATCH vs POST. PUT method creates/replaces the resource at the requested URI. PATCH method modifies the existing resource (partially) at the requested URI. POST method creates/modifies the resource without targeting an URI. After modification, how user can make use of the same resource, that's entirely dependent on the web application logic.

The whole point of PATCH is that you are not sending the entire entity representation, so I don't understand your comments about the empty string. You would have to handle some sort of simple JSON such as:

{ aBoolean: true }

and apply that to the specified resource. The idea is that what has been received is a diff of the desired resource state and the current resource state.

How to do partial updates to REST API resources, [Updated: Feb 23, 2018, Created: Feb 23, 2018] PATCH method modifies the existing resource (partially) at the requested URI. RELEASE: Spring Web MVC. javax.servlet-api 3.0.1 Java Servlet API; jstl 1.2 javax.servlet:jstl; JDK 1.8; Maven​  create a method @Requestmapping with a param @modelattribute. The point here is that the @modelattribute method is the initializer for the model. Then spring merges the request with this model since we declare it in the @requestmapping method. This gives you partial update functionality.

Spring MVC - Handling HTTP PATCH Request, Working on the Spring Boot based monolithic server that clients are to It was best to implement this logic in a base controller that could be inherited by PATCH request body to make it into the method; Load entity being updated and copy its  When they're doing a partial update, they can use HTTP PATCH. For instance, when updating a single field of the Resource, sending the complete Resource representation might be cumbersome and utilizes a lot of unnecessary bandwidth. In such cases, the semantics of PATCH make a lot more sense.

HTTP PATCH Request with Spring Boot and Data Transfer Objects , Learn about the difference between HTTP PUT vs HTTP PATCH in a REST API, and their implications when building your Spring API. replace an existing Resource entirely, For a partial update, we can use HTTP PATCH. Having a clear distinction between different HTTP method while designing REST  Using Spring MVC 3.0, I am developing a member management system with basic CRUD operations and am having trouble with my Controller. I cannot update a member record using a Controller method. I have methods to display and process my 'Add Member' form and another to display my 'Edit Member' form and they all work fine. Here is my controller:

HTTP PUT vs HTTP PATCH in a REST API, This project demonstrates an approach to support HTTP PATCH with JSON Patch and JSON Merge Patch for performing partial modifications to resources in​  Don't use GET as HTTP method for updates. GET is defined to be a safe operation (no side effects), which an update is not. PATCH is the correct method here as it's defined to allow partial updates to an existing resource. To submit form data into PUT and PATCH requests, you need to register an HttpPutFormContentFilter with the application as

Comments
  • I've put together a post that describes an approach for using PATCH in Spring. And a working example is available on GitHub.
  • Seems like a good alternative, I upvoted, but what if someone uses the API and sends {"aVeryBigString":null} instead of {"aVeryBigString":""} to empty the string?
  • null value has to be used only to define that property is not used in update action. If you want to empty the string you have to pass only "". This rule has to be like a convention.
  • When jackson deserializes from the request body all missing fields will be null so you don't even have to explicitly set values to null.
  • PATCH should be only used for sending only the properties to be updated .. according to stackoverflow.com/a/20655696/986160 and williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot
  • Downvoting because sending a PATCH with an attribute that has a null value is intrinsically different than sending a PATCH that does not include a value for an attribute (e.g., for an app adhering to the JSONAPI spec, I would expect the former to unset the attribute, and the later to leave the attribute unchanged).
  • I like this answer. Do you have sample code for the mapper that accomplishes this in a generic fashion so that the same code could apply to each of the entity in the domain instead of having repeating code for each entity class. I assume it would need to use reflection to "sync" each of the property over from the HashMap to the domain model. I also wonder if this would have a performance impact?
  • I just don't get it. How null-values in the Map are distinguishable from unexistent values? If Map implementation permits null-values, then result of map.get(unexistentKey) and map.get(nullValueKey) will be the same. If it doesn't permit null-values, then Jackson can't map json-null to this map. So, the Map isn't any more usable then Pojo to distinguish nulls from non-passed values.
  • @djxak you need to have a convention that if client sends you an empty string then you clear the field - you will be able to detect that with a map. Alternatively, you could use Map.keySet to check which entries you have there (even those which have null values - meaning that the client asks to clear corresponding properties)
  • This is the wrong patch. There's JSON Patch and HTTP Patch (which is a verb like get, post, put, etc). tools.ietf.org/html/rfc5789