Using URIs vs ID to identify resources

@Erika asked this excellent question in yesterdays tech call, but we didn’t get around to discussing it

Question: What is the benefits of converting id to uri and back trough out the system?

This question refers to the way we’ve implemented the models for courses in lernanta, most of badges and also the mechanical mooc

One of the biggest problems with the typical way of using the Django framework in my opinion is implicit dependancies developing between different components of an application over time. This happens because the Django ORM exposes a very thin and intrusive interface between your data and whatever uses the data.

See this code for example. This creates a dependancy between courses and pages which is normal, courses have pages. But it also creates a dependancy on the structure of pages in the database.

Lets say you wish to add a field to indicate that a page is spam and based on this you want the page to not show up in a course. Adding the column to the database is easy, but you have to update all instances where the active pages are retrieved using .filter(deleted=False, listed=True)!

This is a trivial example and dependancies often goes deeper than one level (ex. course.badge.earners.filter(deleted=False) ). This creates a spaghetti mess when you try to maintain or update the code!

Django’s ORM gives you a lot of power and it should, but Django’s ORM should never be your interface between backend logic and the frontend! Some agree with me.

So, to avoid the situation, I chose to wedge an interface between the data and the view. An interfaced that’s designed around the question you want to ask from the data. (Things like give me all the public pages that’s not spam). This interface effectively becomes your model in MVC terms.

This is also limiting, but that’s not a bad thing. You are forced to implement the questions you want to ask from the data in the model interface (AND TEST IT!!).

This doesn’t magically make dependancies disappear though. For instance, a course will still depend on pages and pages in turn may depend on users. To reference an author, a page should probably use a URI for the user. (or a URN, but lets postpone the canonical correctness discusion )

We could still use ID’s instead of URIs for this. The benefit comes in when the separation between your modules grow. For instance, we have two different versions of courses. Let’s say we have a list of courses, we can use URIs for the courses and the URI will imply the type of the course. If the list only requires a subset of the course fields and both course modules returns them, the list can remain ignorant of what is going on behind the scenes with courses.

There is a part that’s still missing: how do you know where to fetch a course from given a URI? if you are doing HTTP APIs you need a URL and if you are doing it on a code level you need a function to call! At some stage we may need to look at something to help with looking up URLs for URIs.

1 Like