Tuesday, February 10, 2009

REST and the Resource

Something that often happens on applications that I've worked on is the need to access a resource in a particular context. For example, you have a application where students submit their homework assignments allowing teachers to grade them.

Using a resource oriented application, you may allow students to access their submitted assignments to make comments, view their grades, etc... using this URI:
/students/avalentin/assignments/

On the other hand a teacher would like to access a particular students assignments with a few more options, such as copy-editing or grading the submission. However making the resource available from the same URI as a student does not provide the context that the teacher is reviewing the item. In that case you may provide a URI that looks like this:
/teachers/cgjung/students/avalentin/assignments/

The great thing about this URI is that it gives you a context, "As a teacher I want to view a students assignments" vs "As a student I want to view the assignments I submitted for grading"

Now Rails makes it easy to accomplish this goal. First make students available as a resource with the following mapping:
map.resources :students

Next make that students assignments available as a nested resource:

map.resources :students do |students|
students.resources :assignments
end

Now you can access a specific students assignments using this URI
/students/{student id}/assignments/{assignment id}

The teachers mapping looks more or less like this:

map.resources :teachers do |teachers|
teachers.resources :students do |students|
students.resources :assignments
end
end

This access a specific students assignments using this URI
/teachers/{teachers id}/students/{student id}/assignments/{assignment id}

That's it really. Well not really. Those mappings actually result in non-human discernible URIs that look like this:
/teachers/9999/students/4353/assignments

Now maybe I'm over analyzing this but my preference would be to have resource identifiers that have a logical meaning that is not tied to some database identity...

No comments: