Overview

Polite HTTP API design – “Use the headers, Luke!”

No Comments

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.

   @RequestMapping(path = PATH, method = RequestMethod.POST)
   public ResponseEntity<SomeEntity> createCustomer(final @RequestBody SomeEntity someEntity, final UriComponentsBuilder uriComponentsBuilder) {
       final SomeEntity savedEntity = someEntityRepository.save(someEntity);
 
       final HttpHeaders headers = new HttpHeaders();
       headers.setLocation(uriComponentsBuilder.path(PATH + "/{id}").buildAndExpand(savedEntity.getId()).toUri());
 
       return new ResponseEntity(someEntity, headers, HttpStatus.CREATED);
   }

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!

“It’s all about data!” – Every application reads and writes information, so Kevin places great emphasis on the smooth and high-performance handling of these data. He has specialized in the use of the Spring Framework and Hibernate and he is also interested in new technologies. Agile software development and the “Clean Code” concept are further foundations of his work.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Comment

Your email address will not be published. Required fields are marked *