It's a good practice to let a client specify the format in Web REST API:

GET /api/items/123.csv

However, not only GET can return some answer, but POST also can do

Status: 201 Created

  mgs: "Your item has created successfully",
  href: "/example.com/items/123"

How should URI look like for a POST (PUT or whatever, but not GET) request which returns a response so that a client can specify the format they want the response to be in? Like this?:

POST /api/items/.csv 

Or suppose there is an error when a client sends a POST request and the server must inform the client about it:

Status: 400 Bad Request
  mgs: "this is a bad request",
  devMessage: "it's bad because ...."
  friendlyMessage: "something bad happened..."

What format should it respond in, why and how do I specify it as a client?

P.S. - I'm aware about REST - Tradeoffs between content negotiation via Accept header versus extensions

  • 2
    POST /api/items.csv is another option? Since you are talking to the resource items? Commented Oct 2, 2013 at 10:17
  • The server isn't required to respect the Accept header, especially when returning an error and not a 200, but it should definitely try to get any Content-Type it sends back to actually describe what it is sending. Commented Oct 3, 2013 at 8:38

3 Answers 3

POST /api/items/.csv 

looks logical only if you give '.csv' special meaning. If not, then it should be interpreted as POST /api/items/.csv/ by the server which I don't think it's what you want. I'm just using this as example where using file extension doesn't work.

Regarding what should be returned, the server should look at the Accept header and respond in acceptable format if it returns any entity at all (4xx responses should return explanation why it was an error).

I think it should be like this:

POST /api/postbox/
Accept: application/json
Content-type: text/csv

If success server returns:

201 Created
Location: /api/items/123.csv

or when fail:

415 Unsupported Media Type
Content-type: application/json
Message-body: { error: "please only post text/csv file." }
  • The only thing wrong with this answer is that the resource is never /api/items/.csv/; that's totally different in general (even if your particular environment happens to make it the same). Commented Oct 3, 2013 at 8:36
  • @DonalFellows maybe it's not obvious, but I don't think it's wrong. I put the trailing '/' there to make it explicit that generally you POST to a resource. If it were a PUT then, yes, it wouldn't be always the case. I also want to detach the file extension association from .csv identifier. Otoh, POST to /api/items/csv could also work if the designer decided that different media type is significant to different users (so he can have /api/items/csv/1.csv /api/items/csv/2.csv). An analogy is that it's common to have /api/help/en/index.html and /api/help/fr/index.html for different languages.
    – imel96
    Commented Oct 3, 2013 at 23:28

The question you linked to addresses what to do when a client GETs from the server, not what to do when the client POSTs to the server.

In your case, the use of the HTTP Accept header won't work as it is the equivilent of a client saying: "Hey give me this resource, but only in these formats."

This is a case where the robustness principle applies:

Be conservative in what you do, be liberal in what you accept from others.

When the client POSTs the data there should be a Content-Type that describes whats being delivered. Where possible, your application should interpret and accept as much as possible before failing. Does it matter if its CSV, JSON, or XML if you application can accept all three?

A single URL for delivery will be easier on your clients, and most likely easier on you. Apart from a slight difference in code to pull the content from the CSV, JSON, XML, whatever, its most likely that once you convert it to a format the application handles internally the data will be treated the same.


Why do you want to send back an URL after a POST request? What's usually done is redirecting to the newly created resource. For example:

Status: 201 Created
Location: /example/items/123

All this in the headers.

Same for when an error happens, the status code is enough. 403 Forbidden means what it says.

With regards to the POST URL, the other question definitely answers that.

  • the question is not about these 2 specific responses but about the general way. Same for when an error happens, the status code is enough this is not enough for sure since there are many other errors can occur.
    – Oskar K.
    Commented Oct 2, 2013 at 15:36
  • what if it were 400 Bad Request?
    – Oskar K.
    Commented Oct 2, 2013 at 15:40
  • @Grienders how is 400 Bad Request not enough? Commented Oct 2, 2013 at 15:50
  • read the question again.
    – Oskar K.
    Commented Oct 2, 2013 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.