Build and Deploy a REST API with Django and Docker — Part 1

This series aims to give a glimpse at how to quickly build a REST API using Django and deploy the same application with docker on multiple major cloud platforms including Amazon Web Services (AWS), Google Cloud Platform (GCP). In this journey, we will be building a simple API for a To-Do application.

To begin with, we need to have an API design in place, which means the list of HTTP endpoints along with their methods, parameters, headers, and response structure. It is common practice in the industry to create an API specification document shortly called API spec before the development starts. This serves as an agreement between the frontend developers and the API developers.


How does our API look

To keep things simple, we will only have a basic set of endpoints even though a good To-Do list application can contain a lot of convenience methods. Below is the list of endpoints we are going to develop.

  • POST /login
  • POST /login/refresh
  • POST /login/register
  • GET /lists/list
  • POST /lists/add
  • GET /tasks/list
  • POST /tasks/add

We will see in detail about each endpoint right before we develop it.

Lets start coding

Before we begin we need to setup our development environment. If you are using Ubuntu machine python is already installed else you can always download the latest version of python for your platform from here. Once you have python and pip ready, lets go ahead and install Django and Django Rest Framework. But, wait this can get quite messy with different versions of the packages. Python has a great way to manage this, Virtual Environments. So first lets install python3-venv and create a virtual environment as below.

$ sudo apt-get install -y python3-venv # installing venv on ubuntu
$ python3 -m venv todo # creating venv called todo
$ source todo/bin/activate # activating the venv

Now lets install Django and Django Rest Framework using pip as shown below

# Installing Django and Django Rest Framework
$ pip install Django
$ pip install djangorestframework

Django provides a good command line tool called django-admin to quickly bootstrap a project. So we will now create ToDo project using django-admin

$ django-admin startproject ToDo

This command will create a folder structure as show below and our first Django app ready. You can start a development server by using manage.py’s runserver command, Now open your browser and go to localhost:8000 to see Django’s landing page.

ToDo
├── manage.py
└── ToDo
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
$ cd ToDo
$ python manage.py runserver

Lets take a look at two important files from the above folder structure.

  • settings.py is the file in which we specify all your configurations like installed apps, django middlewares, database connection details, cache configuration, listen address, debug setting etc. We will discuss in detail about some of the settings when needed but you can always have a look at official docs anytime.
  • urls.py takes care of routing in the app. Here, we specify which view (don’t panic, we will explain what a view is, for time being it is just a python class with some methods to handle http requests) should be called on a particular endpoint or path. This file contains a python list of django.urls.path() instances called urlpatterns. You can have any number of these files and include them in root urls file specified ROOT_URLCONF setting.

Time for hello world!

In Django, views are either classes or functions which take a request and returns a response. Class based views should subclass View class or any of its children and should define an appropriate view method (get, post, put etc.) corresponding to HTTP method.

Lets build a simple GET request which will return hello world. To start with create a views.py file, and create a class for our HelloWorld view which extends APIView class of rest_framework.view. Now, we will define the get method to handle HTTP GET requests, it should take atleast two arguments self and request. In method body, simply return a Response object initialized with a string. The final views.py file will look like below.

#views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class HelloWorld(APIView):
def get(self, request):
return Response('HELLO WORLD! from Django.')

Our view class is ready, Now we have to add a path in urls.py to send the request to the appropriate view. Import the views from current directory and then add a path to urlpatterns as shown below.

from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('hello_world', views.HelloWorld.as_view())
]

We have to add rest_framework to INSTALLED_APPS in settings.py to access any of its functionalities. The installed apps section will look like below.

# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]

Lets try if it works!. Make sure your server is running, open up your browser and hit http://127.0.0.1:8000/hello_world. You should see a Django Rest Framework page with HELLO WORLD! from Django. You can also use curl on terminal to make the same request and it looks like below.

$ curl http://127.0.0.1:8000/hello_world
"HELLO WORLD! from Django."

That’s all for part-1. You can see the source code here. In the next part of this series, we will see how to implement a custom token based authentication and create endpoints for users to register, get tokens and refresh an expired token.