Relational APIs with Node.js Tastypie and RethinkDB

ne of the more tricky and debated topics in API circles is how to handle relational data. How deep into your data tree should it go, how to accept it from the client and how much to return to the client. One could choose to treat each resource as a silo and force the client to individually create each object and piece all of the relations together. However, that is not a great user experience. It also leads to a very large number of requests and data transfer, which has been a blemish on the idea of a REST API for a while. The emergence of modern mobile devices which limited bandwidth and performance profiles need a more streamlined way doing things.

Take, for example, a photo gallery. A Gallery would have zero or more Photos and each Photo would have a set of Tags for categorizing. Lately, I have been enamored with RethinkDB - a beautiful blend of Document storage and relational databases, which allows to model our example in any number of ways. Let's take a traditional approach. In the silo-ed Resource world we would have to create each of those entities from the lowest level up:

Issue a POST request for each Tag

Issue a POST request to create each Photo

Issue a PUT for each Photo to assign tags

Issue a POST request to create the Gallery

Issue a PUT request to add Photos to it

For a new Gallery with 10 Photos with 3 Tags each, that is pushing 50 requests. With the v3.0.0 release of Tastypie-Rethink, you link any number of resources together to handling the relationship management for you. More importantly, expose an API that makes this process significantly easier for end clients. Install the required NPM packages

API [eɪ.piˈaɪ], -n, --noun

abbreviation for application programming interface: a way of communicating with a particular computer program or internet service

Simple - it isn't pretty or perfect, but it will illustrate the example. Now, we need to expose the API by setting up and linking our resource. The Tastypie Rethink package ships with 3 new field types to do this: hasone, hasmany, and document

Field Types

HasOne: The hasone field handles direct relations, or foreign key relations. In the thinky world this is the hasOne and belongsTo relation type.

HasMany: the hasmany field handles one-to-many and many-to-many relations. In the thinky world the is the hasMany and the hasAndBelongsToMany relation types

Document: The document field is for dealing with is commonly referred to as subdocuments or nested objects. These do not get saved to the database in a separate table, but provide a layer of validation, formatting and consistency over user input. They are also included in the endpoint schema definition for greater introspection be clients.

Done. That's it. We have a Photo Gallery API that can handle all sorts of incoming data. Let's create a new photo gallery with 3 photos with 3 tags each. To do that, we need to post all of the data as a single json document with all of the data inlined :

By default Relations will be returned as URIs, which in can be used in place of full objects to form relations. This also cuts down on the payload sizes. So for the above example, you would get a response like the following:

The RethinkDB resource for tastypie exposes a great deal of functionality in 3 new field types ( hasone, hasmany and document ) and some additional filters to dealing with dates ( year, month and day ) making it dead simple to stand up expressive and usable ReST APIs in minutes

I'm a software developer and system architect working at help.com. Most of my day is spent working with Javascript & Node.js. I've also done a good deal of web and print design work in my day. I created this space to share my experiences with the world and hopefully learn something in the process.

This Space

Here you will find my ramblings and rants about web development. My focus is around JavaScript( MooTools, Sencha, NodeJS ), Python & Django, HTML & CSS. Most things here target a wide range of skill levels - from the very simple to the moderately complicated. You may also find the occasionaly personal ranting and I may stand on a soap box from time to time.