When developing web applications, sometimes we need to abstract the way we interact with data, so that we can access it and modify it easily and have a it available to be consumed from different devices and other applications.
A web API, is exactly that, it's a set of defined requests and responses that allow us to communicate with a server, consume and edit the data it offers.
There are several approaches to API design, however, one architectural style that has become very popular, is
REST, it stands for Representational State Transfer. The idea behind REST, is to use HTTP verbs to represent CRUD actions.
So, for example, if you're going to work with a resource
users, you can use these HTTP verbs to request the server a specific CRUD action.
GET /users/1 Get user with id 1
POST /users/ Create a new user
PUT /users/1 Update user with id 1
DELETE /users/1 Delete user with id 1
Django REST Framework
On the other hand, Django Rest Framework integrates very well with
Django and enhances it with several useful Classes and functions.
Overview of the Todo's API
We're going to go over some of the aspects of building a simple API. For the following sections, we've put together a
GitHub repository with a Todo's JSON API, we recommend you clone it in order to follow along with the article.
This API, has a basic
Task model, and a serializer
TaskSerializer which will take care of serializing the task so that we can return them as JSON data.
Cloning and installing the Todo's API
<pre lang="bash"># Clone the repository<br/>$ git clone https://github.com/AxiaCore/todomvc-django.git<br/># Install the requirements<br/>$ pip install -U -r requirements.txt<br/># Sync the database<br/>$ ./manage.py syncdb<br/># Start the server<br/>$ ./manage.py runserver<br/></pre>
At this point, you should be able to go to
http://localhost:8000 and use the Todo's app which communicates with its REST API.
In the example app, we only have one model,
Task, it has two attributes,
<pre lang="python">from django.db import models<br/>class Task( models.Model ):<br/> """<br/> Model for storing `tasks`<br/> """<br/> # Whether this task is completed<br/> completed = models.BooleanField( default = False )<br/> # Task title<br/> title = models.CharField( max_length = 100 )<br/></pre>
Serializers allow for native Django data like Models and Querysets to be converted to objects, lists, arrays etc, so that they can be easily returned as JSON or XML data. In this app, we're going to be using JSON.
from rest_framework import serializers from task.models import Task class TaskSerializer( serializers.ModelSerializer ): """ Serializer to parse Task data """ class Meta: model = Task fields = ( 'title', 'completed', 'id' )
In this serializer, we're also returning the
Task id so that we have a reference to it if we want to update or delete it.
Django Rest Framework, offers several classes that can help us handling requests, and removing the boilerplate from our view methods.
We're going to take a look at how this API uses class based views. In the example app repository, the views are built using both function and class based views, so that you can take a look at how each one would be implemented.
class TaskMixin(object): """ Mixin to inherit from. Here we're setting the query set and the serializer """ queryset = Task.objects.all() serializer_class = TaskSerializer class TaskList(TaskMixin, ListCreateAPIView): """ Return a list of all the tasks, or create new ones """ pass class TaskDetail(TaskMixin, RetrieveUpdateDestroyAPIView): """ Return a specific task, update it, or delete it. """ pass
In this mixin, we want to get the
queryset and the
serializer_class which will be common for all our view classes. Then, we will inherit it from other views.
serializer_class is the used to specify which is the serializer class we want to use, in this case,
TaskSerializer which is based on
queryset, is the list of
Tasks objects we to serializer and return.
We're inheriting from this class because it provides handlers for both
This class, provides endpoints for
DELETE which we will be using to work with a single
<pre lang="python">urlpatterns = patterns('',<br/> # Include API URLs<br/> url( r'^api/', include( 'api.urls' ) ),<br/>)<br/></pre>
urlpatterns = patterns('', # Include API URLs url( r'^api/', include( 'api.urls' ) ), )
One of the coolest features of Django Rest Framework, is its browseable API documentation, it gets generated automatically after you define your views.
To take a look at the API documentation, just go to
http://localhost:8000/api/tasks/ and you should see the lists of created
Tasks as well as some relevant information about the API and its endpoints like the kind of data they accept, the data they might return and the like.
If you haven't cloned the example app, you can take a look at how a documentation would look like by following this
At this point, you should have a basic understanding of what's an API, REST, and how Django Rest Framework works. If you want to learn more, following there are some resources that might be helpful for you.