Building REST API with Django REST Framework
27 Oct 2016We’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:
GET statuses/show/:id
GET statuses/user_timeline
POST statuses/update
POST statuses/destroy/:id
For this project, I want to follow REST best practices. Here the API would look like:
GET /statuses
- Retrieves a list of statusesGET /statuses/:id
- Retrieves a specific statusPOST /statuses
- Creates a new statusDELETE /statuses/:id
- Deletes status id
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.