In this article, I perform a comparative study on building a basic REST API using major Python-based frameworks — Django, Flask, and FastAPI.
But first, what is REST?
REpresentational State Transfer is a set of standards that defines how operations on web-apps access data following a group of predefined operations. It has been accepted ubiquitously due to its simplicity and efficiency.
REST API provides various options for a request depending on the type of operation. The two most common requests are:
- GET — This request may or may not provide some filter parameters in the URI, which returns the matching data.
- POST — This request creates a new record in the data. The parameters are provided in the request body. RFC 7231 defines that a successful POST request should — “send a 201 (Created) response containing a Location header field that provides an identifier for the primary resource created
and a representation that describes the status of the request while referring to the new resource(s)”
Other operations may use PUT, DELETE, HEAD, OPTIONS, and PATCH requests.
Django: The star-studded all-rounder.
Django is undoubtedly one of the most powerful frameworks for web development. Exploiting the power (flexibility, ease of use, community support) of Python is a secure and scalable framework widely accepted by the community. I have worked on various frameworks and languages; Django’s admin panel and ORM (Object-Relational Mapper) provide robust development and easier testing.
Let’s build a basic REST API on Django using DRF. (Note: It is possible to build a REST API without DRF, but it is always preferred to use DRF since it makes a lot of other operations such as security, access control, and serialization easy and synchronized with the Django ORM)
Assuming you have Django installed already. Let’s start by installing DRF in your virtual environment.
pip install djangorestframework
Now, we add our dependency (DRF) in settings.py
Next, we are going to write the views for displaying our data. Consider our models.py to consists of class Person(name, age, email). We need to display this Model in the form of
JSON since we are making a REST API. This process is known as serialization. Though you can use the serializer available in
django.core, DRF provides us with serialization that can validate and process complex data easily.
The serializer automatically retrieves the fields from models and creates a serializer for the Person class.
Let’s use this serializer to list our Person objects. DRF provides us with generic views that are commonly used in web development. For this example, we will be using
ListCreateAPIView, various other generic views that can be found in the DRF documentation here. (Note: The default methods can be overridden to provide an additional layer of customization)
An example with the class-based views is:
If you prefer customizing using function-based views, you can define functions get(), post(), create() that override the default functions and you can modify them accordingly.
Thus we see how using DRF’s generics reduces the amount of effort required to create mundane views and even perform access control and serialization.
Next, we jump on to Flask.
Flask: the easy prototyping framework.
Flask is a VERY simple framework and yet a powerful python web framework. Flask does not natively provide an ORM and requires to perform a manual connection to the DB. Nevertheless, a Flask API can be created in a single file since it is really simple to setup for prototyping applications.
Assuming you already have Flask installed in your virtual environment, let’s start by creating our
First, we make the necessary imports and start a Flask app. To design a ListCreate view, we provide a parameter to the app.route decorator called methods=[‘GET’,’POST’] defines the allowed request methods on this route. We use
flask.jsonify to convert our response in JSON, we divide our code of listing and creation based on the type of request we receive.
As we see, Flask is easier and faster to develop, but as the project gets more complex and scales, Flask falls short due to its lack of features. But for small projects, Flask provides a better and easier experience.
Next, we study our newest member of the club — FastAPI.
FastAPI — The name says it all.
FastAPI is a recently developed Python-based web framework that is based on Starlette and Pydantic. For those who don't know about Starlette, it is an ASGI (Asynchronous Server Gateway Interface) framework based on Python. Traditionally, WSGI (Web Server Gateway Interface) has been used to run and host python codes on the web. ASGI is lightweight and natively supports async requests which can be used to improve load handling and response time. Pydantic on the other hand is data validation library that uses Python type hinting.
Add alt text
FastAPI is indeed really fast. It natively supports the following functionalities:-
- OpenAPI documentation using two default options — SwaggerUI and ReDoc.
- Parameter Validation using Pydantic
- GraphQL support
- Easy Testing
Let’s start with making a basic REST API using FastAPI
pip install fastapi
Installs FastAPI in our venv
Thanks to pydantic, we can define our schema using pydantic and use sqlalchemy to have an ORM that can perform CRUD operations from our app (just like Django does ;-;)
pip install sqlalchemy
Let’s structure our project in the following manner:
| — main.py Entrypoint for the service
| — models.py
| — db.py connects to db
| — CRUD.py contains the functions to perform Create Read Update and Delete operations
We are focusing on developing the REST API, so I will be skipping the other files for now but will be covering them later on in a future edit. More details on here.
Response_model can be used to change the output schema in some cases, such as when creating new users, you do not want to return the password in the input model.
We run the
main.py file now with
That’s it! FastAPI also makes testing easy using Pytest. Along with that, it also provides OpenAPI docs and information about your models and their validations using Pydantic. FastAPI deserves more attention and can be adopted to deploy scalable, fast, and easy-to-maintain servers quickly.