Skip to content
guilhermesilveira edited this page Feb 15, 2011 · 2 revisions

Content negotiation

What is content negotation?

REST clients know how to deal with several different media types, for instance application/xml and application/opensearchdescriptor+xml. Being so, when requesting something to your service, a client tells which media types it is capable of understand so the service provides the best fit between the ones both of them are capable of handling.

Content negotiation

Content negotiation is the key concept that allows services to change their links to other parts of other systems while not breaking compatibility with their consumers (clients).

Because the new linked services supports a set of media types that so does your client, changes can be made and nothing breaks.

Client side content negotiation

By default, all Restfulie client requests will not add anything to the Accept header so the server is free to provide the representation using any media type:

Response response = Restfulie.at('http://myhotels.caelum.com/1').get();
Hotel hotel = reponse.getResource();
System.out.println(hotel.getName());

By executing the above code, the client is unaware of which media type was used. Typical clients will notify its client API (Restfulie) which media types it is capable of handling. The following source code shows how to add the Accept header with the json option:

        //The accept method put the media type on the request header, informing the server about which type it can handle
	Response response = Restfulie.at("http://myhotels.caelum.com/1").accept("application/json").get()
	// print the media type used to produce the response
	System.out.println(response.getHeaders("Content-type"));

	Hotel hotel = reponse.getResource();
	System.out.println(hotel.getName());

The client can also use the 'Content-type' http reader to communicate with the server about the media type which the the information been sent is represented.

Card card = new Card(4444);
// The as() method will set the content type of the information been sent, this example sent the card as an xml  
// but expect an anwser as json
Response response = Restfulie.at("http://myhotels.caelum.com/1").as("application/xml").accept("application/json").post(card)

If both Content-type and Accept must be informated as above, and with the same representation, you can use the handling() method as a shortcut for it.

	Card card = new Card();
	// The handling() method will add application/xml for both Accept/Content-type header	
	Response response = Restfulie.at("http://myhotels.caelum.com/1").handling("application/xml").post(card)
	// print the media type used to produce the response
	System.out.println(response.getHeader("Content-type"));

Media types supported

Currently Restfulie Java supports the default xml and json representations.

Custom media types on the client side

<p>dunno what to write yet</p>

Unnacepted

If the service does not understand the media type sent, it will return a 406 Unaccepted response. The client is responsible for checking the response status and act accordingly.

Restfulie goes ahead and provides something more. The ConnegWhenUnaccepted feature allows your clients to retry a request if the service did not accept the media type you tried to send.

The client will automatically check if any of the media types supported by the service (through the Accept response header) is supported by the client itself, if so, it will re-send the response using the new media type.

Look at the features page for more details.