MarkUs Blog

MarkUs Developers Blog About Their Project

Recent MarkUs RESTful API Changes

without comments

As many of you may have heard I have been working on updating and adding on to the existing MarkUs RESTful API. In this blog I will cover some of my previous and upcoming changes to the API. For those who are not familiar with REST or looking for more background about our API, feel free to read up on Danesh’s blog post: http://blog.markusproject.org/?p=2866

 

Submitted Changes:

1.) Error messages that are created by us have been remade. Before we would reference the error specific HTML/XML files found in the /public directory. We now have HTML/JSON/XML/TEXT templates for various format types. A pretty straight forward example:

render 'shared/http_status', :locals => { :code => "200", :message => HttpStatusHelper::ERROR_CODE["message"]["200"] }, :status => 200

This type of call will return a 200 OK response with the given message in whatever format the user has specified through the URL or  the HTTP Accept header, which brings me to my next change.

2.) Responses are now returned in the user specified format. Currently this only works for collection/member GET requests for the users API and any error responses for any API controller. In addition I am using the same methods for the upcoming assignments API.

Upcoming Changes:

1.) In the past, to retrieve a specific user we would query: http://localhost:3000/api/users/1?user_name=Joe

In this case, the 1 is a completely irrelevant number and could really be any ( valid ) string. This may have been implemented so because of the restrictions placed on us by Rails for using the resourceful routing.

Consider the GET routing table entry for the users member: GET /api/users/:id(.:Format). As developers we would have to retrieve params[:id] to get the value passed in through the URL and this may seem misleading as this value would then be treated as a user_name inside the function*.

It is not easy to change :id to :user_name within the routing table and I see this as a necessary evil, introduced by Rails, that we will just have to cope with. As such, I have made the change to remove the need for the user to specify these garbage ids and the above example now looks much cleaner as:  http://localhost:3000/api/users/Joe

* Note that we only work with ids for URLs on the main website, but for the API we prefer to deal with the much more friendly “names”. Of course these names have to be set to be unique within the model.

2.) Reworking the routing to nest resources within each other. As an example, before we may have queried the following URL to retrieve test_results: http://localhost:3000/api/test_results?group_name=Group&assignment=A1

As suggested by Severin, I have made the change to change the above example to:  http://localhost:3000/api/groups/Group/assignmentA1/test_results

While the bellow URL may seem to seem more readable, I cannot help but feel that we are flirting with the dark side of Rails here. During my routing work I have found a recommendation made by Rails developers: “Resources should never be nested more than 1 level deep.” as can be seen on http://guides.rubyonrails.org/routing.html#limits-to-nesting. Are we really doing the right the right thing by making this change? I am open to suggestions.

3.) Last but not least, I will be adding the API for assignments. I will not be doing anything too crazy here, but instead stick to the functionality that we already provide through the website. For those brave enough, I have started uploading my changes here: http://review.markusproject.org/r/1206/

Written by ephilippov

April 7th, 2012 at 10:40 pm

Posted in Uncategorized

Leave a Reply