An easier to use Java REST client

I recently was duped (by myself) at a discussion with a colleague: in our continuous effort to disentangle release schedules of two tightly entangled applications, I exposed some core features as a JSON REST service and told him to “just use the Spring invoker” for JSON. It turns out, there is one for JaxRS, Burlap, Hessian, RMI… but nothing for a generic JSON service.
Pondering over this obvious lack of a facility which binds a JSON service to a java interface it occurs that it’s not exactly trivial: how do you know the URL a method should be bound to? Which HTTP method do you use? GET? POST? PUT? Do you post parameters as URL parameters or are they part of the url path? I.e.
/books/1-2345-678  vs  /books/?isbn=1-2345-678
A JSON REST service does not expose it’s structure, so there is no automatic way of binding a Java interface to it.
So I came up with the spring-rest-invoker [1] which binds a java interface to a remote JSON REST service. The idea behind is simple: define a interface and declare the concrete mappings to URLs and HTTP methods via Spring annotations such as @RequestMapping:
public interface BookService {

    @RequestMapping("/volumes")
    QueryResult findBooksByTitle(@RequestParam("q") String q);

    @RequestMapping("/volumes/{id}")
    Item findBookById(@PathVariable("id") String id);
}
Create a proxy to it:

<bean id="RemoteBookService"
        class="com.github.ggeorgovassilis.springjsonmapper.HttpJsonInvokerFactoryProxyBean">

Use and enjoy:

@Autowired
RemoteBookService bookService;

...

QueryResult results = bookService.findBooksByTitle("Alice in Wonderland");

Cool things you can do:

  • It converts JSON to Java value objects when reading and the other way around when posting
  • You can define method parameters to map to parts of the URL via @PathVariable or being sent as URL parameters via @RequestParam
  • You can post a single Java object which will be directly JSON-ified
  • You can post multiple Java objects, then every object will be a named field in a JSON object (you have to use @RequestParam in that case to assign the name)
  • You can provide your own RestTemplate in case you need to hook into the HTTP communication

Resources

[1] Spring http invoker

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.