4

One of our APIs has a tasks resource. Consumers of the API might create, delete and update a given task as they wish.

If a task is completed (i.e., its status is changed via PUT /tasks/<id>), a new task might be created automatically as a result.

We are trying to keep it RESTful. What would be the correct way to tell the calling user that a new task has been created? The following solutions came to my mind, but all of them have weaknesses in my opinion:

  1. Include an additional field on the PUT response which contains information about an eventual new task.
  2. Return only the updated task, and expect the user to call GET /tasks in order to check if any new tasks have been created.

Option 1 breaks the RESTful-ness in my opinion, since the API is expected to return only information regarding the updated entity. Option 2 expects the user to do stuff, but if he doesn't then no one will realize that a new task was created.

Thank you.

UPDATE: the PUT call returns an HTTP 200 code along the full JSON representation of the updated task.

@tophallen suggests having a task tree so that (if I got it right) the returned entity in option 2 contains the new task as a direct child.

cafonso
  • 909
  • 11
  • 18
  • You could try to add a new header in the response, something like X-New-Task which identifies the new task. – cyber_rookie Mar 24 '15 at 07:07
  • I'm assuming in case 2 you are returning 202's? Has a task tree been considered? - I would think a task caused _as a direct result_ of another task would be considered to have relation to the updated entity, and thus be relevant as a property of the result. – tophallen Mar 24 '15 at 07:07
  • @tophallen We are returning plain 200s with the full JSON reprsentation of the entity after the update (we are following this interpretation of the whole RESTful paradigm: http://stackoverflow.com/a/798174/624356). A task tree could be an option as well, but I would like to avoid using a tree structure just for the sake of solving this issue (although we might go for it if no other alternative is found). – cafonso Mar 24 '15 at 07:20
  • @cyber_rookie Would that be considered a good practice? – cafonso Mar 24 '15 at 07:26
  • It doesn't seem to be that bad of an idea, but given what you're trying to achieve, it seems like an option, although it might have some bottlenecks such as some firewalls that rewrite HTTP headers. – cyber_rookie Mar 24 '15 at 07:29

2 Answers2

1

You really have 2 options with a 200 status PUT, you can do headers (which if you do, check out this post). Certainly not a bad option, but you would want to make sure it was normalized site-wide, well documented, and that you didn't have anything such as firewalls/F5's/etc/ re-writing your headers.

Something like this would be a fair option though:

HTTP/1.1 200 OK
Related-Tasks: /tasks/11;/tasks/12

{ ...task response... }

Or you have to give some indication to the client in the response body. You could have a task structure that supports child tasks being on it, or you could normalize all responses to include room for "meta" stuff, i.e.

HTTP/1.1 200 OK
{
    "data": { ...the task },
    "related_tasks": [],
    "aggregate_status": "PartiallyComplete"
}

Something like this used everywhere (a bit of work as it sounds like you aren't just starting this project) can be very useful, as you can also use it for scenarios like paging.

Personally, I think if you made the related_tasks property just contain either routes to call for the child tasks, or id's to call, that might be best, lighter responses, since the client might not always care to call to check on said child-task immediately anyways.

EDIT: Actually, the more I think about it - the more headers would make sense in your situation - as a client can update a task at any point during the task processing, there may or may not be a child task in play - so modifying the data structure for the off-chance the client calls to update a task when a child task has started seems more work than benefit. A header would allow you to easily add a child task and notify the user at any point - you could apply the same thing for a POST of a task that happens to immediately finish and kicks off a child task, etc. It can easily support more than one task. I think this as well keeps it the most restful and reduces server calls, a client would always be able to know what is going on in the process chain. The details of the header could define, but I believe it is more traditional in a scenario like this to have it point to a resource, rather than a key within a resource.

If there are other options though, I'm very interested to hear them.

Community
  • 1
  • 1
tophallen
  • 1,033
  • 7
  • 12
0

It looks like you're very concerned about being RESTful, but you're not using HATEOAS, which is contradictory. If you use HATEOAS, the related entity is just another link and the client can follow them as they please. What you have is a non-problem in REST. If this sounds new to you, read this: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Option 1 breaks the RESTful-ness in my opinion, since the API is expected to return only information regarding the updated entity.

This is not true. The API is expected to return whatever is documented as the information available for that media-type. If you documented that a task has a field for related side-effects tasks, there's nothing wrong with it.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85