27

I'm designing a RESTful web service using WebApi and was wondering what HTTP responses and response bodies to return when updating / creating objects.

For example I can use the POST method to send some JSON to the web service and then create an object. Is it best practice to then set the HTTP status to created (201) or ok (200) and simply return a message such as "New Employee added", or return the object that was sent originally?

The same goes for the PUT method. Which HTTP status is best to use and do I need to return the object that was created or just a message? Considering the fact that the user knows what object they are trying to create / update anyway.

Any thoughts?

Example:

Add new Employee:

POST /api/employee HTTP/1.1
Host: localhost:8000
Content-Type: application/json

{
    "Employee": {
        "Name" : "Joe Bloggs",
        "Department" : "Finance"
    }
}

Update existing employee:

PUT /api/employee HTTP/1.1
Host: localhost:8000
Content-Type: application/json

{
    "Employee": {
        "Id" : 1
        "Name" : "Joe Bloggs",
        "Department" : "IT"
    }
}

Responses:

Response with object created / updated

HTTP/1.1 201 Created
Content-Length: 39
Content-Type: application/json; charset=utf-8
Date: Mon, 28 Mar 2016 14:32:39 GMT

{
    "Employee": {
        "Id" : 1
        "Name" : "Joe Bloggs",
        "Department" : "IT"
    }
}

Response with just message:

HTTP/1.1 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8
Date: Mon, 28 Mar 2016 14:32:39 GMT

{
    "Message": "Employee updated"
}

Response with just status code:

HTTP/1.1 204 No Content
Content-Length: 39
Date: Mon, 28 Mar 2016 14:32:39 GMT
  • 1
    Good question, but using the term "best-practice" is sort of taboo on this site meta.programmers.stackexchange.com/questions/2442/… You might just want to re-word the question. meta.programmers.stackexchange.com/questions/6967/… – Snoop Mar 28 '16 at 14:59
  • 2
    As a bit of a follow-up, would it be a good idea to have a flag in the request so that (for example) a mobile application can get the whole object returned when on WiFi, but only the ID when using cellular data? Is there a header that should be used for that to avoid polluting the JSON? – Andrew Piliser Mar 28 '16 at 20:46
  • @AndrewPiliser Interesting idea, although I personally think it's just best to pick one approach and stick to it. Then as your application develops or becomes more popular, optimise it – iswinky Mar 29 '16 at 7:17
  • @AndrewPiliser your idea is very similar to the Postgresql UPDATE/INSERT ... RETURNING variant for SQL. It's extremely handy, especially as it keeps the submission of new data and request for the updated version atomic. – beldaz Jul 10 '18 at 10:40
26

As with most things, it depends. Your tradeoff is ease of use versus network size. It can be very helpful for clients to see the created resource. It may include fields populated by the server, such as last-creation-time. Since you appear to be including the id instead of using hateoas, clients will probably want to see the id for the resource they just POSTed.

If you don't include the created resource, please do not create an arbitrary message. The 2xx and Location fields are enough information for clients to be confident that their request was properly handled.

  • +1 The hateoas objective of not letting the client compose the uri's can also be achieved by by allowing the client to fill in server provided URL templates with specific ID's. Yes, the client "composes" but only in a "fill in the blanks" kind of way. While not pure HATEOAS it achieves the objective and makes working with objects that have a (large) number of "action" uri's a bit less bandwidth sensitive, not to mention when you put those objects in a (largish) list. – Marjan Venema Mar 29 '16 at 11:26
  • 3
    +1 on the "please do not create an arbitrary message" advice – HairOfTheDog Jun 13 '17 at 20:12
9

@iswinky I would always send back the payload in case of both POST and PUT.

In case of POST you might create the entity with an internal ID or a UUID. Hence it makes sense to send back the payload.

Similarly in case of PUT, you might ignore some fields of the user (immutable values, say), or in case of a PATCH, the data might have been changed by other users as well.

Sending the data back as it was persisted is always a good idea and definitely doesn't harm. If the caller has no need for this returned data, then he/she won't process it but will just consume the statusCode. Else they can use this data as something to update the UI with.

It's only in case of a DELETE that I wouldn't send back the payload and would do either a 200 with a response content, or a 204 with no response content.

  • I can see many situations where sending back the entire payload is a bad idea, when the payload is large. – beldaz Jul 10 '18 at 10:42
  • 1
    @beldaz completely agree. YMMV based on the design of the REST API. I generally avoid very large objects and break it down into a series of sub-resources / PUTs. If the payload is very large there are better ways to do this, and therein you would want to do HATEOAS (like Marjan says above) where you return the reference to the object instead of the object itself. – ksprashu Jul 11 '18 at 11:20
9

Personally, I always return only 200 OK.

To quote your question

Considering the fact that the user knows what object they are trying to create / update anyway.

Why add extra bandwidth (which might have to be paid for) to tell the client what it already knows?

  • 1
    That's what I was thinking, if it's invalid you can return validation messages, but if it's valid and gets created / updated then check the HTTP status code and show the user a message e.g "Hooray" based on that – iswinky Mar 29 '16 at 11:29
  • 2
    See stackoverflow.com/a/827045/290182 regarding 200/204 No Content to avoid confusing jQuery and the like. – beldaz Jul 10 '18 at 10:44
4

Referencing to the link RFC standards, you should return 201(created) status on successfully storing the request resource using Post. In most of the applications the id of the resource is generated by the server itself, so it is good practice to return the id of the created resource. Returning the whole object is the overhead for Post request. Ideal practice is to return the URL location of the newly created resource.

For example you can refer to the following example that saves the Employee Object into the database and returns the URL of the newly created resource object as a response.

@RequestMapping(path = "/employees", method = RequestMethod.POST)
public ResponseEntity<Object> saveEmployee(@RequestBody Employee employee) {
        int id = employeeService.saveEmployee(employee);
        URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(id).toUri();
        return ResponseEntity.created(uri).build();
}

This rest endpoint will return the response as:

Status 201 - CREATED

Header Location →http://localhost:8080/employees/1

protected by gnat Oct 23 '18 at 9:17

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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