Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Official way to implements PATCH method in REST with partial update

I definitely didn't find clear way to do partial updates quite automatically (possible by comparing field by field object in databse and partial object).

I saw some tracks like :

  • here but I don't know what is its magic MapperService
  • here but quite ugly, I'm sure a better solution exists
  • here but I don't know what's is the heavyResourceRepository Repository Type for which save(Map<String, Object> updates, String id) method is used
  • or can/must we use ModelMapper to map not null fields?
  • or here overriding copyProperty method

Thank you, PATCH method is available but I didnn't see clear way to implemtns it.

like image 501
Danton Avatar asked Feb 16 '18 10:02

Danton


1 Answers

You can use @RepositoryRestResource to do that for you.

When you export your endpoint like this:

@RepositoryRestResource(path = "some_entity")
public interface SomeEntityRespostiory extends JpaRepository<SomeEntity, Integer> {

}

You are exposing all the option of a default CRUD, and you will not need a controller class.

You can use PUT to replace all your entity fields. Or you can use PATCH to replace just some fields from your entity.

This PATCH method will be in charge to update only the fields you actualy recieve from your payload.

For example:

@Entity
@Getter
@Setter
@NoArgsContructor
public classe SomeEntity {

    @Id
    private Integer id;
    private String name;
    private String lastName;
    private LocalDate birthDate;
    private Integer phoneNumber;
}

To you create your register:

curl -i -X POST -H "Content-Type:application/json" -d 
'{"name": "Robert", "lastName": "Downey", "bithDate": "1965-4-4", "phoneNUmber":2025550106}'
http://localhost:8080/some_entity

To replace all your record you use:

curl -i -X PUT -H "Content-Type:application/json" -d 
'{"name": "Robert", "lastName": "Downey", "bithDate": "1965-4-4"}'
http://localhost:8080/some_entity/{id}

in this case the variable "phoneNumber" will be null.

But, if you try this:

curl -i -X PATCH -H "Content-Type:application/json" -d 
'{"lastName": "Downey Jr.", "bithDate": "1965-4-15"}'
http://localhost:8080/some_entity/{id}

Only the "lastName" and "birthDate" will be updated.

This is awesome because you don't have to worry about it.

You can see more about that in this documentation. Search for word "Patch" and you can find some examples.

If you need make some verification, for example: the name need to have at least three words. You can put a EventHandler like this:

@Component
@RepositoryEventHandler
public class SomeEntityHandler {

    @Autowired
    private SomeEntityService someEntityService;

    @HandleBeforeCreate
    @HandleBeforeSave
    public void save(SomeEntity someEntity) {
        someEntity.verifyStringSize(someEntity.name);
    }
}

And then you can throw your exception, or change the all the string to uppercase string, or anything else you want.

like image 76
Aron Richter Avatar answered Sep 19 '22 01:09

Aron Richter