Bowman is a Java library for accessing a JSON+HAL REST API.
-
Simplified API consumption via automatic, lazy link traversal on an annotated client-side model
-
Tailor made for Spring Data REST
-
Analogous interface to JPA
-
RESTful CRUD and templated link query support
-
Polymorphic deserialisation
Standing on the shoulders of Spring HATEOAS and Jackson.
Given the following annotated model objects:
@RemoteResource("/people")
public class Person {
private URI id;
private String name;
public Person() {}
public Person(String name) { this.name = name; }
@ResourceId public URI getId() { return id; }
public String getName() { return name; }
}
and
@RemoteResource("/greetings")
public class Greeting {
private URI id;
private Person recipient;
private String message;
public Greeting() {}
public Greeting(String message, Person recipient)
{ this.message = message; this.recipient = recipient; }
@ResourceId public URI getId() { return id; }
@LinkedResource public Person getRecipient() { return recipient; }
public String getMessage() { return message; }
}
Client instances can be constructed and used as demonstrated below.
The HTTP requests/responses corresponding to each instruction are shown in a comment beneath.
ClientFactory factory = Configuration.builder().setBaseUri("http://...").build()
.buildClientFactory();
Client<Person> people = factory.create(Person.class);
Client<Greeting> greetings = factory.create(Greeting.class);
URI id = people.post(new Person("Bob"));
// POST /people {"name": "Bob"}
// -> Location: http://.../people/1
Person recipient = people.get(id);
// GET /people/1
// -> {"name": "Bob", "_links": {"self": {"href": "http://.../people/1"}}}
assertThat(recipient.getName(), is("Bob"));
id = greetings.post(new Greeting("hello", recipient));
// POST /greetings {"message": "hello", "recipient": "http://.../people/1"}}
// -> Location: http://.../greetings/1
Greeting greeting = greetings.get(id);
// GET /greetings/1
// -> {"message": "hello", "_links": {"self": {"href": "http://.../greetings/1"},
// "recipient": {"href": "http://.../people/1"}}}
assertThat(greeting.getMessage(), is("hello"));
recipient = greeting.getRecipient();
// GET /people/1
// -> {"name": "Bob", "_links": {"self": {"href": {"http://.../people/1"}}}
assertThat(recipient.getName(), is("Bob"));