The goal of this is to build a Grails application that uses a REST servive as a backend.
The REST endpoint is implemented using RESTEasy from the JBoss guys.I have a “create” endpoint, which takes an object of type “Content”, stores it using its own backend and then returns the URI to the newly created object in the HTTP Location header.
The server looks something like this:
@Path("/")
@Produces("application/json")
@Consumes("application/json")
public class RESTEndpoint {
@POST
@Path("/create")
public Response create(Content content, UriInfo uriInfo) {
Long contentId = contentService.create(content);
URI newURI = uriInfo.getBaseUriBuilder().path("/content/{key}").build(contentId);
return Response.created(newURI).build();
}
The point is that the HTTP response produced by this will set the Location header, but it will NOT contain any body. According to HTTP 1.1 this is perfectly legal:
10.2.2 201 Created
The request has been fulfilled and resulted in a new resource being
created. The newly created resource can be referenced by the URI(s)
returned in the entity of the response, with the most specific URI
for the resource given by a Location header field. The response
SHOULD include an entity containing a list of resource
characteristics and location(s) from which the user or user agent can
choose the one most appropriate.
[...]
So the key phrase is “The response SHOULD include an entity…” but it doesn’t HAVE TO.
But, when we use Grails’ REST client, the following results in an exception from the client:
render withRest(uri: "http://cey-linux:8080/restservice/") {
def resp = post(path : 'create',
body: '{ "content":{"name":"My Content"}}"',
requestContentType: "application/json")
resp.getHeaders("Location")
}
I don’t have the exception handy but will reproduce and paste it here.
To fix this problem, I now send the URI of the new content object in the Location header and in the body of the response:
return Response.created(newURI).type(MediaType.TEXT_PLAIN).entity(newURI).build();
This also makes us compatible with HTTP 1.0, which requires that a body is sent in case of response status 201-Created.