Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST partial update with @PATCH method

Tags:

java

rest

spring

I'm trying to implement a partial update of the Manager entity based in the following:

Entity

public class Manager {
    private int id;
    private String firstname;
    private String lastname;
    private String username;
    private String password;

    // getters and setters omitted
}

SaveManager method in Controller

@RequestMapping(value = "/save", method = RequestMethod.PATCH)
public @ResponseBody void saveManager(@RequestBody Manager manager){
    managerService.saveManager(manager);
}

Save object manager in Dao impl.

@Override
public void saveManager(Manager manager) {  
    sessionFactory.getCurrentSession().saveOrUpdate(manager);
}

When I save the object the username and password has changed correctly but the others values are empty.

So what I need to do is update the username and password and keep all the remaining data.

like image 288
wilson Avatar asked Jul 19 '17 20:07

wilson


People also ask

Which rest method is used to update a resource partially?

The HTTP PATCH request method applies partial modifications to a resource. PATCH is somewhat analogous to the "update" concept found in CRUD (in general, HTTP is different than CRUD, and the two should not be confused).

Does PUT method applies a partial update to an existing resource?

PUT. The HTTP PATCH method should be used whenever you would like to change or update just a small part of the state of the resource. You should use the PUT method only when you would like to replace the resource in its entirety.

Can you do a partial update?

Partial updates are allowed by PUT (according to RFC 7231 https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4). ",... PUT request is defined as replacing the state of the target resource." - replacing part of object basically change state of it.

Which annotation is recommended for partial updates of resources in Spring Boot rest controller?

The PATCH HTTP method is used when you want to apply a partial update to the resource and @PatchMapping annotation for mapping HTTP PATCH requests onto specific handler methods.


1 Answers

If you are truly using a PATCH, then you should use RequestMethod.PATCH, not RequestMethod.POST.

Your patch mapping should contain the id with which you can retrieve the Manager object to be patched. Also, it should only include the fields with which you want to change. In your example you are sending the entire entity, so you can't discern the fields that are actually changing (does empty mean leave this field alone or actually change its value to empty).

Perhaps an implementation as such is what you're after?

@RequestMapping(value = "/manager/{id}", method = RequestMethod.PATCH)
public @ResponseBody void saveManager(@PathVariable Long id, @RequestBody Map<Object, Object> fields) {
    Manager manager = someServiceToLoadManager(id);
    // Map key is field name, v is value
    fields.forEach((k, v) -> {
       // use reflection to get field k on manager and set it to value v
        Field field = ReflectionUtils.findField(Manager.class, k);
        field.setAccessible(true);
        ReflectionUtils.setField(field, manager, v);
    });
    managerService.saveManager(manager);
}
like image 79
lane.maxwell Avatar answered Oct 12 '22 12:10

lane.maxwell