Gilang Chandrasa Thoughts, stories, and ideas

Building REST API with Django REST Framework

We’re building a simple Twitter Clone. In this posts, we’ll start with REST API.

What is REST?

Representational state transfer (REST) or RESTful web services are one way of providing interoperability between computer systems on the internet. REST-compliant web services allow requesting systems to access and manipulate textual representations of web resources using a uniform and predefined set of stateless operations - Wikipedia

If you want to know more about REST and its best practices, you can read Best Practices for Designing a Pragmatic RESTful API article by Vinay Sahni.

This what status Twitter API look like:

For this project, I want to follow REST best practices. Here the API would look like:

What is Django REST Framework?

Django REST Framework or DRF is a powerful toolkit to help you building REST API in your Django application.

Installation

Install DRF using pip

pip install djangorestframework

Add 'rest_framework' to your INSTALLED_APPS setting.

INSTALLED_APPS = (
    ...
    'rest_framework',
)

This is optional but if want to use browsable API you’ll need this.

urlpatterns = [
    ...
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

Let’s Begin

The project structures, we use versioning for REST API v1

    manuk
    ├── apps
    │   ├── __init__.py
    │   ├── api
    │   │   ├── __init__.py
    │   │   └── rest
    │   │       ├── __init__.py
    │   │       └── v1
    │   │           ├── __init__.py
    │   │           ├── serializers.py
    │   │           ├── urls.py
    │   │           ├── views.py
    │   └── timelines
    │       ├── __init__.py
    │       ├── admin.py
    │       ├── migrations
    │       │   ├── 0001_initial.py
    │       │   ├── __init__.py
    │       ├── models.py
    ├── manage.py
    ├── manuk
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   ├── wsgi.py
    └── templates

Here our simplified models for this tutorial. (apps/timelines/models.py)

from django.conf import settings
from django.db import models
from django.template.defaultfilters import truncatechars


class Status(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    text = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'statuses'

    def __unicode__(self):
        return truncatechars(self.text, 20)

Create serializers for our application (apps/api/rest/v1/serializers.py)

from rest_framework import serializers

from timelines.models import Status


class StatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = Status
        fields = ('id', 'text', 'user')

Create views API, the simplest way is to use generic class-based views. (apps/api/rest/v1/views.py)

from rest_framework import generics

from timelines.models import Status
from .serializers import StatusSerializer


class StatusList(generics.ListCreateAPIView):
    queryset = Status.objects.all()
    serializer_class = StatusSerializer


class StatusDetail(generics.RetrieveDestroyAPIView):
    queryset = Status.objects.all()
    serializer_class = StatusSerializer

Map the URL for API (apps/api/rest/v1/urls.py)

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns

from . import views

urlpatterns = [
    url(r'^statuses/$', views.StatusList.as_view()),
    url(r'^statuses/(?P<pk>[0-9]+)/$', views.StatusDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

Add above URL mapping to main urls.py (manuk/urls.py)

That’s it. It really easy to add REST support with Django REST Framework. Run the dev server and open your browser, go to localhost:8000/api/v1/statuses/ to play around with the API.