Spring REST and PATCH Method

I am using SpringBoot and Spring REST. I would like to understand the HTTP PATCH method to update the properties of my model

Is there a good tutorial explaining how to make it work?

  • HTTP PATCH method and body to send
  • Controller method and method for controlling the update operation.
+8
source share
3 answers

In the PATCH method, there is nothing fundamentally different from Spring from PUT and POST . The challenge is what you pass in your PATCH request and how you map the data in the controller. If you match your bean value with @RequestBody , you will need to determine what is actually set and what the null values ​​mean. Other options would be to limit PATCH requests to a single property and specify it in the URL or map values ​​to Map . See Also Spring. MVC PATCH Method: Partial Updates

+2
source

I noticed that many of the answers provided are all JSON fixes or incomplete answers. Below is a full explanation and an example of what you need to work with real code.

First of all, PATCH is a selective PUT. You use it to update any number of fields for an object or list of objects. In PUT, you usually send the entire object with any updates.

PATCH / object / 7

 { "objId":7, "objName": "New name" } 

PUT / object / 7

 { "objId":7, "objName": "New name", "objectUpdates": true, "objectStatus": "ongoing", "scoring": null, "objectChildren":[ { "childId": 1 }, ............ } 

This allows you to update records without a huge number of endpoints. For example, using the above, to update the score, you need the / {id} / scoring object, then to update the name you need the / {id} / name object. There is literally one endpoint for each item, or you require the interface to send an entire object for each update. If you have a huge object, it can take a lot of time on the network or mobile data that is not needed. The patch allows you to have 1 endpoint with the minimum values ​​of the object properties that the mobile platform should use.

Here is an example of the actual use of the patch:

 @ApiOperation(value = "Patch an existing claim with partial update") @RequestMapping(value = CLAIMS_V1 + "/{claimId}", method = RequestMethod.PATCH) ResponseEntity<Claim> patchClaim(@PathVariable Long claimId, @RequestBody Map<String, Object> fields) { // Sanitize and validate the data if (claimId <= 0 || fields == null || fields.isEmpty() || !fields.get("claimId").equals(claimId)){ return new ResponseEntity<>(HttpStatus.BAD_REQUEST); // 400 Invalid claim object received or invalid id or id does not match object } Claim claim = claimService.get(claimId); // Does the object exist? if( claim == null){ return new ResponseEntity<>(HttpStatus.NOT_FOUND); // 404 Claim object does not exist } // Remove id from request, we don't ever want to change the id. // This is not necessary, you can just do it to save time on the reflection // loop used below since we checked the id above fields.remove("claimId"); fields.forEach((k, v) -> { // use reflection to get field k on object and set it to value v // Change Claim.class to whatver your object is: Object.class Field field = ReflectionUtils.findField(Claim.class, k); // find field in the object class field.setAccessible(true); ReflectionUtils.setField(field, claim, v); // set given field for defined object to value V }); claimService.saveOrUpdate(claim); return new ResponseEntity<>(claim, HttpStatus.OK); } 

The above can be confusing for some people, as new developers usually do not deal with this reflection. In fact, no matter what you pass to this function in the body, it will find the corresponding statement using the given identifier, and then ONLY update the fields that you pass as a key-value pair.

Body example:

PATCH / CLAIM / 7

 { "claimId":7, "claimTypeId": 1, "claimStatus": null } 

The above will update ApplicTypeId and ClausStatus to the indicated values ​​for clause 7, leaving all other values ​​unchanged.

So the return will be something like this:

 { "claimId": 7, "claimSrcAcctId": 12345678, "claimTypeId": 1, "claimDescription": "The vehicle is damaged beyond repair", "claimDateSubmitted": "2019-01-11 17:43:43", "claimStatus": null, "claimDateUpdated": "2019-04-09 13:43:07", "claimAcctAddress": "123 Sesame St, Charlotte, NC 28282", "claimContactName": "Steve Smith", "claimContactPhone": "777-555-1111", "claimContactEmail": " steve.smith@domain.com ", "claimWitness": true, "claimWitnessFirstName": "Stan", "claimWitnessLastName": "Smith", "claimWitnessPhone": "777-777-7777", "claimDate": "2019-01-11 17:43:43", "claimDateEnd": "2019-01-11 12:43:43", "claimInvestigation": null, "scoring": null } 

As you can see, the complete object would return without changing any data other than what you want to change. I know that there is a slight repetition, I just wanted to outline it clearly.

+1
source

Create a vacation template with -

 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; RestTemplate rest = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); now make the PATCH call ResponseEntity<Map<String, Object>> response = rest.exchange(api, HttpMethod.PATCH, request, responseType); 
-6
source

Source: https://habr.com/ru/post/986369/


All Articles