Skip to content
Mykola Kokalko edited this page Aug 16, 2016 · 9 revisions

Hypermedia representations

A Restful application should support hypermedia content, and following this constraint, a typical resource representing an order in xml would add controls (links or forms) so clients can navigate through your service protocol (in this case, make a payment):

<order xmlns:atom="http://www.w3.org/2005/Atom">
  <name>rails training</name>
  <description>REST training</description>
  <price>512.45</price>
  <atom:link rel="self" href="http://www.caelum.com.br/orders/1" />
  <atom:link rel="payment" href="http://www.caelum.com.br/orders/1/payment" />
</order>

Here the order is represented through a typical application/xml file, but it has something extra: controls that allows clients to decide what to do next. Or an example of a valid json representation with hypermedia:

{ "order" : 
  { "name" : "rails training",
    "description" : "rest training",
    "price" : "512.45",
    "links" : 
    {  "link" : { "rel" : "self", "href" : "http://www.caelum.com.br/orders/1"},
       "link" : { "rel" : "payment", "href" : "http://www.caelum.com.br/orders/1/payment"}
    }
  }
}

Last of all, one could add the links on the Link header of the http response:

<%= html 'Link: <http://www.caelum.com.br/orders/1>; rel="self", <http://www.caelum.com.br/orders/1/payment>; rel="payment"' %>

Server side

Restfulie server side is provided through the VRaptor a simple and expressive MVC framework . This is a simple example how to make your controllers available to your resource consumers. When returning a resource you are able to say which media type should be used i.e "application/xml".

@Resource
public class OrdersController {

  private Result result;

  public OrdersController(Result result){
    this.result = result;
  }

  @Get
  @Path("/items/{id}")
  public void show(Long id){
    Order order = new OrderDAO().load(id);

    // vraptor will serialize the order as an json() format
    result.use(json()).from(order).serialize();
  }
}

VRaptor uses XStream to serialize the order object based on the given representation. Although XStream can easily generate it for us without any further configuration, we must configure our object to generate the hypermedia links. For it we need to implement the HypermediaResource interface.

public class Order implements HypermediaResource {

  private Long id;
  private String name;
  private String description;
  private Double price;

  //getters and setters
        
  //Through the builder object we are able to configure which hypermedia links will be returned with our resource
  public void configureRelations(RelationBuilder builder) {
    //with an easier to read DSL we can easily configure our links
    builder.relation("self").uses(OrdersController.class).show(id);
    builder.relation("payment").uses(OrdersController.class).payment(id);
  }
}

Client side

When thinking in REST apis, it can imagine one (may a few) entry points, and then interact with the application using hypermedia links that were returned. Here is how to do it using the restfulie-java api:

//getting an instance of restfulie
Restfulie restfulie = Restfulie.custom();

//It will register the Order class on the XML media type, so that it will be able to convert it.
restfulie.getMediaTypes().register(new XmlMediaType().withTypes(Order.class))
	
//retrieves the resource through GET: the entry point
Response response = restfulie.at("entry point").accept("application/xml").get();

//the resource method understand the xml and return the Order object previous registered	
Order order = response.getResource();
	
//print the order price
System.out.println(order.getPrice());
	
//send a post request to create a payment
Payment payment = new Payment(new Card(444), new Amount(order.getCost()));
resource(order).link("payment").follow().post(payment);
	
//send a delete request to cancel the order
resource(order).link("cancel").follow().delete();

This should be all. Requesting the order with the header Accept or the extension xml should get you back a hypermedia supported xml file. With the json and atom versions everything should work accordingly.

By now you should be able to put your resources online and hypermedia-link them whenever they make sense. Do not forget to use hypermedia controls to notify your client the URIs to use for creating and updating content too, as with the payment example above.

Clone this wiki locally