We have an existing web app that can score an essay.
A user can start a new revision of an essay, save it, resume it or submit it (for scoring). Once the revision is submitted it is marked as a COMPLETE and it is not later changed. If the user starts a new revision the previous response will be copied to the current revision. If the user resumes the revision - he works with the current revision (that is IN PROGRESS). The saved but not submitted revision is 'IN PROGRESS' state.
We need to design an API that would allow to do the same things in the client app.
As the first step we need to get the latest version of the essay (it might be in progress or complete or not existing yet (so return just a template)).
GET user/{userid}/revisions/mostrecent
The format of revision would be sth like this
<revision>
<id> </id>
<response> </response>
<status> </status>
</revision>
Later the client app should send the changed revision.
However I am not sure how to deal with different states of the essay revision ('IN PROGRESS', 'COMPLETE'), i.e. should the client app perform different PUT/POST operation based on the revision state or should it just POST sth and everything should be handled server-side (i believe it not RESTful API then)?
I would think that sending a new revision would be:
POST user/{userid}/revisions
And updating the current revision:
PUT user/{userid}/revisions/{id}
But how to distinguish that the revision should only be saved not submitted (by setting the status to 'INPROGRESS')?
And how to prevent from creating multiple IN PROGRESS revisions (the POST wouldn't be executed if there is already 'INPROGRESS' revision)?
How to prevent from updating the previous revisions (if status = COMPLETE then PUT is forbidden?)
Thanks for any hints or suggestions.
-
But how to distinguish that the revision should only be saved not submitted (by setting the status to 'INPROGRESS')?
If you're passing in the id as an argument, doesn't that infer in itself that the revision should be saved? Is the {Id} for the essay or the revision? If it's for the essay, then just create an id for the revision (or maybe even just a datetime stamp) and then pass that along in the restful URI as well...
PUT user/{userid}/essays/{id}/revisions/{revisionId}
You can use a locking mechanism on the essay to prevent concurrent revisions (or a database lock if you are using Sql Server), and a 'Completed' flag sounds like a good idea to me to prevent updating previous revisions.
matali : The id is for the revision (we're using both names: revision and essay for the same thing). -
You can send data in a PUT/POST request that provides the status. Its necessary is cases like these, or any other case where you modify the record without "committing" it in some sense. In fact, what you're actually doing is a RESTful transaction.
Your other questions require business logic in your application. REST only tells you to return an appropriate status code in response to a request; it doesn't dictate how and if you should process a request depending on the state of your data.
That being said, the loose logic for what you asked is:
if is_new_revision() and old_revision_is_pending(): return "409 Conflict" if revision_id != most_recent_revision_id: return "403 Forbidden" -
Thanks for the answers.
So I understand that to mimic the behavior of our web app there should be a logic on client side as well. It's not enough to have one generic command like POST/PUT revisions for all cases (starts a new revision, resume the previous one). The client should distinguish the case if the revision is IN PROGRESS it can be saved/submitted but it can't be if it's COMPLETE (and all other situations).
-
Have you considered using WebDAV with versioning for this task? I think it would be much more robust than rolling your own protocol on top of HTTP.
-
Specifying URI naming conventions like "GET user/{userid}/revisions/mostrecent" violates one of the constraints of RESTful architecture. You cannot define URIs or URI templates for resources as part of your API, if you want to call it RESTful.
See http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven for more information.
0 comments:
Post a Comment