We are developers and largely we are also practitioners. This means, in general we want to get things done, preferably quickly. But apart from doing our daily work and implementing required features, thinking a few steps ahead is really valuable. Can you improve something without spending much effort? In other words, what about harvesting the low-hanging fruits while also being nice to future users?
For example, do you think about headers when you write HTTP controllers? Do you specify it explicitly and in detail? Be honest! In my experience headers are treated as some kind of inevitably existing metadata, maybe it’s even annoying to handle them, and that attitude is wrong. After discarding this bad habit, leveraging headers can be really helpful fulfilling requirements and they can do it in a neat way.
Let’s talk about the Location header to demonstrate that in practice. It offers a huge benefit to the consumer of your API with a small effort on development side.
Assume you have to implement an HTTP endpoint to make creation of new resources possible via POST. Usually, you have to create a unique identifier on server side, maybe some kind of ID, to identify this new resource. Of course, the consumer of your API does not know that ID at request time, but there is no doubt, sooner or later the caller needs this information to address the created object. The “rude” way is to force the caller to parse the response and extract this identifier from the response body. That’s not polite. There is a more sophisticated way to communicate the new resource location – the Location header.
When returning the response, also return the Location header filled with the absolute URI to the created resource, for example: Location: http://domain.tld/resource/123
. With that information the user can continue without parsing the response body.
Projects like Spring Data REST return this header automatically when @RepositoryRestResource is in use and returning a proper header via your own MVC controllers is also possible with minimum effort.
Since Spring 3.1 there is a simple way to get this done, the UriComponentsBuilder comes to the rescue. Just inject it into your controller and complete it with the endpoint path and with the ID of the resource. Now you can return an HttpHeaders object containing a Location header with this URI and the consumer is free to decide if he still wants to parse the response or use this header.
1@RequestMapping(path = PATH, method = RequestMethod.POST)
2 public ResponseEntity<SomeEntity> createCustomer(final @RequestBody SomeEntity someEntity, final UriComponentsBuilder uriComponentsBuilder) {
3 final SomeEntity savedEntity = someEntityRepository.save(someEntity);
4
5 final HttpHeaders headers = new HttpHeaders();
6 headers.setLocation(uriComponentsBuilder.path(PATH + "/{id}").buildAndExpand(savedEntity.getId()).toUri());
7
8 return new ResponseEntity(someEntity, headers, HttpStatus.CREATED);
9 }
A github demo project with tests for both the Spring Data Repository and the own controller is available to give it a try.
That is just one example of what the implementation could look like. No matter what software stack is in use, just look out for simple improvements!
More articles
fromKevin Peters
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Kevin Peters
Senior IT Software Engineer / Consultant
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.