90

I am using RESTlet and I have created a resource. I handle POST by overriding acceptRepresentation method.

The client should send me some data, then I store it to DB, set response to 201 (SUCCESS_CREATED) and I need to return some data to the client, but return type of acceptRepresentation is void.

In my case, I need to return some identificator so that client can access that resource.

For example, if I had a resource with URL /resource and the client sends POST request I add a new row in DB and its address should be /resource/{id}. I need to send {id}.

Am I doing something wrong? Does REST principles allow to return something after POST? If yes, how can I do it, and if no what is the way to handle this situation?

Ivan Aracki
  • 3,668
  • 8
  • 47
  • 63
del-boy
  • 3,351
  • 2
  • 24
  • 38

5 Answers5

97

REST just says that you should conform to the uniform interface. In other words, it says you should do what POST is supposed to do as per the HTTP spec. Here is the quote from that spec that is relevant,

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

As you can see from this, you have two places where you can indicate to the client where the newly created resource resides. The Location header should have an URL that points to the new resource and you can return an entity with the details also.

I'm not sure what the difference between overriding acceptRepresentation() and overriding post() but this example shows how to return a response from a POST.

Community
  • 1
  • 1
Darrel Miller
  • 129,370
  • 30
  • 183
  • 235
  • 2
    @del-boy: See Thom's answer for how to set the response body from within acceptRepresentation(). – Avi Flax Dec 02 '09 at 15:25
  • 1
    The HTTP spec quote doesn't prohibit a response, if you look in Section 6 it is clear on that: it is permitted: `Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.` – MikeF Aug 17 '15 at 19:19
  • @MikeF It wasn't my intention to infer that a response body was not allowed. The part of the spec I quoted specifically says "and contain an entity". I should have been clearer in my text. – Darrel Miller Aug 18 '15 at 03:38
16

I'd forgo sending anything in the body of the response. Just set Location: to the (full) URL of the newly created resource.

Your description suggests that this is exactly the semantics you:

  1. POST a thing to create it
  2. Respond with enough to know two things:
    1. That the creation happened (the 201)
    2. Where to find the new thing (the Location header)

Anything else is superfluous.

cdent
  • 339
  • 1
  • 6
  • Not that Wikipedia is always a good source, but [that](https://en.wikipedia.org/wiki/HTTP_location) also claims _"[...] To provide information about the location of a newly created resource. In this circumstance, the Location header should be sent with an HTTP status code of 201 or 202."_ – Arjan Jun 13 '17 at 12:44
  • 1
    POST may execute logic that creates one or more resources. The result of the processing may be needed by the client. So, returning it in the response avoids the need to make one or more GET calls to the API. The data created/changed by the POST method may not be (and often isn't) superfluous to the client. – Paulo Merson Aug 09 '17 at 16:42
10

Two different questions:

Does the REST application pattern support returning data in a POST?

I don't think REST explicitly disallows it, but the preferred treatment is spelled out in Darrel's answer.

Does the RESTlet framework allow returning data in a POST?

Yes, even though it returns void, in a class which extends Resource, you have full access to the Response object object via the getResponse() method. So you can call getResponse().setEntity() with whatever data you want.

Thom
  • 124
  • 2
6

Output it in whatever format is requested. That might be:

<success>
    <id>5483</id>
</success>

Or:

{ "type": "success", "id": 5483 }

It depends on what you usually do. If they're not expecting the data, they should just ignore it, but any client that wants to handle it properly should be able to.

Samir Talwar
  • 13,792
  • 3
  • 39
  • 63
  • Ok, I have two possible formats (html and xml). I know how to handle type of requested format, but I don't know how to add data to response. represent method returns Representation, so I just return what ever I want, but acceptRepresentation is void method, so I can't return any data... – del-boy Dec 02 '09 at 00:24
1

If you respond 201 Created with an entity body, rather than a Location redirect, then it's a good idea to include a Content-Location header pointing to the resource that is being represented in the response.

This will avoid potential confusion - in which a client could (justifiably) assume that the response entity actually represents a new state of the 'creator', and not the created resource.

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>
Mike
  • 3,332
  • 1
  • 14
  • 15
  • 3
    I think Content-Location is for a different purpose. The HTTP spec says Content-Location is not defined for POST and PUT. The Location header is used with a 201-Create. Returning a Location does not do automatically do a redirect, you need a 3XX response code for that. – Darrel Miller Dec 02 '09 at 12:21
  • 1
    The location header is used (in a 201 response) to indicate where a the created resource is located; it is not relevant to the entity body of the response it accompanies. My point was that - if you wanted to include the created resource in the 201 response itself (rather than directing/redirecting the client to another URI) then a content-location header would be a good idea. This is probably 'bending the rules' a bit, but it's more efficient than requiring another request/response cycle to get the state of the new resource to the client. – Mike Dec 02 '09 at 13:32
  • Make sense to me. I've never used the Content-Location header before. – Darrel Miller Dec 02 '09 at 16:15
  • if the client is a human with a browser, returning 201 with Location header makes no sense. The user won't know what to do with it. if the client is a robot, it can be programmed know how to deal with it - like a follow up GET on the Location. – irreputable Dec 02 '09 at 17:46
  • 3
    @irreputable: I believe that REST was meant for designing APIs, where A does not stand for a User Agent which looks for some HTML to render. – Hermes Dec 11 '13 at 13:09