What Are We Going To Build
In today's world, building a scalable and performant REST API is crucial for any modern web application. Although planning and developing such solution requires time, we often need to code something really fast for a proof of concept. In this blog I'll use Flask framework and it's extension Flask-RESTful to quickly build an REST API for a ToDo application. We will use SQLite as data base and SQLAlchemy for the ORM. We will use Flask-SQLAlchemy extension for SQLAlchemy support into Flask. Finally, we will dockerize our ToDo web applicaiton.
Planning & Coding The Project
Our web applicaiton will be very simple. We save our todo tasks in the database and retrive them. We need to create:
- A POST Api to save a task into the database.
- A GET Api to retrive the tasks.
So we will use a model class
Task and create these two API's around it.
We will sturcture our project like bellow:
todo-project/ todoapp/ __init__.py models.py schemas.py views.py requirements.txt venv/ .flaskenv
Prepare the Development Environment
To begin, we will create the project folder
todo-project. Inside this folder, we need to set up a virtual environment called
venv and activate it. Please note that the following example is for a Linux-based system, and the commands may vary slightly for Windows.
$ pip install virtualenv~
$ cd todo-projecttodo-project
$ virtualenv venvtodo-project
$ source venv/bin/activate
Now we need to install the required packages for this project. The
requirements.txt file for this is:
Each package can be installed separately or this file can be copied and all required packages can be installed in a single command.
$ pip install -r requirements.txt
Building The Todo App
We will add a Python package named
todoapp inside the
todo-project directory. A Python package is simply a directory that contains an
__init__.py file. While this file is often empty in many packages, in our project structure, the
__init__.py file plays an important role. We will use it to initialize the core components, such as the Flask application and SQLAlchemy database.
In this file, we are primarily responsible for initializing various components of the project. The database URI will create the
todo.db file in the parent directory of the
todoapp directory. To use the
flask run command, we need to create a
.flaskenv file in the
todo-project directory. In this file, we will define the required environment variables. The
flask run command relies on the
FLASK_APP environment variable to determine the name of the file that contains the Flask application. In our case, the Flask application is contained in the
__init__.py file of the
todoapp package, so we can set
FLASK_APP=todoapp here. Additionally, we will utilize another environment variable,
FLASK_RUN_HOST=0.0.0.0, to ensure that the app is externally visible.
models.py file consists of a single model named
Task, which represents a task in our application.
We have used Flask-SQLAlchemy to define our table and columns. For serializing and deserializing data, we will be using Marshmallow. Similar to SQLAlchemy, Flask also has an integration package with Marshmallow called Flask-Marshmallow, which we will utilize. We will add a
schemas.py file in the
todoapp directory, where we will define our
We will now create the API endpoints by adding another file called
views.py inside the
todoapp directory. In this file, we will define a Resource class called
TaskResource. In Flask-RESTful, a Resource class represents an entity or a collection of entities that can be exposed through an API. This class provides a set of methods that can be overridden to define the behavior of the resource for different HTTP methods such as GET, POST, PUT, DELETE, and more. Since we are only interested in creating a todo task and retrieving tasks, we will be overriding the
Our API is ready now and we can run it with command
flask run. There is a single endpoint
/api/todo for creating and retrieving tasks.
Dockerizing The Project
Dockerizing a project means packaging your application, along with its dependencies and configurations, into a
Docker container. For Dockerizing the first we need to create a
Dockerfile. We will create this into the
We will build our Docker image using the
python:3.10-alpine base image. Within the container, we will set the working directory to
/app and copy our
requirements.txt file, installing the necessary dependencies. Next, we'll copy all the files from our existing directory into the
/app directory. If there are any files we want to exclude, we can specify them in a
.dockerignore file. Finally, we'll execute the
flask run command to start the application.