IN the last few posts I have been trying out Springs REST API. For the create operation we had used a POST call. The API would take an user
resource, create it and return the user resource in the response stream.
This approach of returning the created resource has served me fine. However traversing the net has revealed some best practices. One such practice related to Create operation requires:
My APIs have generally been used from AJAX libraries where the best approach seemed to return the created request for use in UI. The resources were also pretty small. But if we developing for heavy resources than the above approach of using Location headers seems a good option. Accordingly I added an additional CREATE method in my User API:
The code to test the same is:
On running the code the logs at server is:
This approach of returning the created resource has served me fine. However traversing the net has revealed some best practices. One such practice related to Create operation requires:
- The API need not return the created resource in the Response Stream.
- It should return an empty response body.
- Instead the API must return a HTTP Status 201 indicating the resource was created.
- Also in the location header of the response it must return a URL needed to access the newly created resource. The client can if it needs fetch the new resource by making a GET call to the returned URL.
My APIs have generally been used from AJAX libraries where the best approach seemed to return the created request for use in UI. The resources were also pretty small. But if we developing for heavy resources than the above approach of using Location headers seems a good option. Accordingly I added an additional CREATE method in my User API:
@RequestMapping(value = "/new", method = RequestMethod.POST) public ResponseEntity<Void> addRedirectUser(@RequestBody final User newUser) { // create the new resource this.addUserToSystem(newUser); logger.info("addRedirectUser : new wine added with id " + newUser.getId()); final URI location = ServletUriComponentsBuilder .fromCurrentServletMapping().path("/user/{id}").build() .expand(newUser.getId()).toUri(); final HttpHeaders headers = new HttpHeaders(); headers.setLocation(location); final ResponseEntity<Void> entity = new ResponseEntity<Void>(headers, HttpStatus.CREATED); return entity; }To return the dynamic location URL I used the ResponseEntity instance. The body was set to type Void. The Headers included the new URL. The response Entity created was written back by The DispatcherServlet. (Note: No ResponseBody annotation was used here)
The code to test the same is:
public User createUserV2(final User newUser) { final HttpEntity<User> userRequest = new HttpEntity<User>(newUser); final URI createdURI = this.restTemplate.postForLocation(userServiceUrl + "new", userRequest); return this.restTemplate.getForObject(createdURI, User.class); }Here we have used the postforLocation method. The method reads the URL from the location header of the response and returns it. A get call was then made to fetch the newly created entity.
On running the code the logs at server is:
2013-06-15 18:35:24 INFO RestServiceController:102 - addRedirectUser : new wine added with id 3 2013-06-15 18:35:24 DEBUG ServletInvocableHandlerMethod:129 - Method [addRedirec tUser] returned [<201 Created,{Location=[http://localhost:8080/SampleRest/api/us er/3]}>] ... 2013-06-15 18:35:24 DEBUG DispatcherServlet:913 - Successfully completed request 2013-06-15 18:35:24 DEBUG XmlWebApplicationContext:322 - Publishing event in Web ApplicationContext for namespace 'dispatcher-servlet': ServletRequestHandledEven t: url=[/SampleRest/api/user/new]; client=[127.0.0.1]; method=[POST]; servlet=[d ispatcher]; session=[null]; user=[null]; time=[703ms]; status=[OK] ... 2013-06-15 18:35:24 DEBUG DispatcherServlet:819 - DispatcherServlet with name 'd ispatcher' processing GET request for [/SampleRest/api/user/3] 2013-06-15 18:35:25 INFO RestServiceController:66 - getUser with id 3 ... 2013-06-15 18:35:25 DEBUG DispatcherServlet:913 - Successfully completed request 2013-06-15 18:35:25 DEBUG XmlWebApplicationContext:322 - Publishing event in Web ApplicationContext for namespace 'dispatcher-servlet': ServletRequestHandledEven t: url=[/SampleRest/api/user/3]; client=[127.0.0.1]; method=[GET]; servlet=[disp atcher]; session=[null]; user=[null]; time=[515ms]; status=[OK]As seen, the client made two calls -
- A POST call to create the new record
- A GET call to return the newly created record.
2013-06-15 18:35:23 DEBUG RestTemplate:78 - Created POST request for "http://loc alhost:8080/SampleRest/api/user/new" 2013-06-15 18:35:23 DEBUG RestTemplate:592 - Writing [com.test.controller.User@1 f2cea2] using [org.springframework.http.converter.json.MappingJacksonHttpMessage Converter@1dc0e7a] 2013-06-15 18:35:24 DEBUG RestTemplate:473 - POST request for "http://localhost: 8080/SampleRest/api/user/new" resulted in 201 (Created) 2013-06-15 18:35:24 DEBUG RestTemplate:78 - Created GET request for "http://loca lhost:8080/SampleRest/api/user/3" ... User created with id 3
Credits for providing this functional content. It helped me a whole lot in understanding as I was looking for this form of tips.
ReplyDeleteKraft Mailer Boxes
Pink Mailer Boxes
Kanarya Adaları yurtdışı kargo
ReplyDeleteKanada yurtdışı kargo
Kamerun yurtdışı kargo
Kamboçya yurtdışı kargo
Jersey yurtdışı kargo
3RC