Introducing FastAPI
Now we will look at a brief introduction to the Python REST-API framework of choice – FastAPI. Additionally, we will go over a high-level overview of the features that make it a protagonist in our FARM stack. I will try to compare FastAPI with Python and JavaScript alternatives and explain why it can be a great fit for a modern and flexible stack.
REST APIs
What is an API? Technically, API stands for Application Programming Interface. APIs are used to enable some kind of interaction between different pieces of software and different systems, and they communicate using HTTP (short for Hypertext Transfer Protocol) through a cycle of requests and responses. In the last couple of decades, APIs have become the standard protocol for communication between various servers and heterogeneous clients, and they can be seen as a sort of vascular system that is fundamental to information exchange on the web.
There are many definitions, more or less formal ones, and application programming interfaces can mean many things, but I like to view them as wirings that expose the business logic through a uniform interface, allowing us to use them from another realm.
An API is, as its name suggests, an interface. It is a way for a human or a machine to interact with an application or a service through an interface. Every API provider will provide an interface that is well-suited for the type of data that they provide, for instance, a weather forecasting station will provide an API that lists the temperatures and humidity levels for a certain period and a certain location. Some sports sites will provide statistical data about the games that are being played and a pizza delivery API will provide you with the selected ingredients, the price, and the estimated time of arrival. APIs are everywhere – inside your TV, your wallet, and, heck, your favorite news site probably uses at least a dozen of them. With the adoption of the Internet of Things, APIs will enter even more aspects of our lives, transmitting biometric and medical data, enabling fast communications between factory machines, tractors in the fields, traffic frequencies, traffic light control systems, and more. APIs are what makes today’s web turn, what generates traffic, and ultimately, what generates revenue. Put simply, we can think of an API as a standardized way of information exchange, with usability, performance, and scalability in mind.
We will not go over the rigorous definitions of REST APIs, but just list some of the most important ones:
- Statelessness: REST APIs are said to be stateless, which means that neither the client nor the server stores any states in-between. All the requests and responses are handled by the API server in isolation and without information about the session itself.
- Layered structure: In order to keep the API scalable and understandable, a RESTful architecture implies a layered structure. The different layers form a hierarchy and communicate with each other but not with every component, thus improving overall security.
- Client-server architecture: APIs should be able to connect different systems/pieces of software without limiting their own functionalities – the server (the system that provides the response) and the client (the system making the request) have to stay separate and independent from each other.
We will be using FastAPI for our REST API layer, and we could say that it checks all the required boxes and then some more.
What is FastAPI?
FastAPI is a modern and performant web framework for building APIs. Built by Sebastian Ramirez, it uses, to best avail, the newest features of the Python programming language, such as type hinting and annotations, the async – await
syntax, Pydantic models, web socket support, and more.
There are numerous reasons why FastAPI, though relatively new, will probably see a wider spread in the web development world in the future, so let’s list some of them:
- High performance: FastAPI is able to achieve very high performance, especially compared to other Python-based solutions. By using Starlette under the hood, FastAPI’s performance reaches levels that are usually reserved for Node.js and Go.
- Data validation and simplicity: Being heavily based on Python types and Pydantic brings numerous benefits. Since Pydantic structures are just instances of classes the developers define, we can perform complex data validations, deeply nested JSON objects, and hierarchical models (using Python lists and dictionaries), and this relates very well with the nature of MongoDB.
- Faster development: Development becomes more intuitive, with strong integrated development environment (IDE) support, which leads to faster development time and fewer bugs.
- Standards compliance: FastAPI is standard-based and fully compatible with open standards for building APIs – OpenAPI and JSON schemas.
- Logical structuring of apps: The framework allows for structuring of APIs and apps into multiple routers and allows granular request and response customization. and easy access to every part of the HTTP cycle.
- Async support: FastAPI uses an Asynchronous Server Gateway Interface (ASGI) and, with the use of an ASGI-compatible server, such as Uvicorn or Hypercorn, is able to provide a truly asynchronous workflow without actually having to import the Async.io module into Python.
- Dependency injection: The dependency injection system in FastAPI is one of its biggest selling points. It enables us to create complex functionalities that are easily reusable across our API. This is a pretty big deal and probably the feature that makes FastAPI ideal for hybrid web apps – it gives developers the opportunity to easily attach different functionalities to the REST endpoints.
- Great documentation: The documentation of the framework itself is excellent and second to none. It is both easy to follow and extensive.
- Automatic documentation: Being based on OpenAPI, FastAPI enables automatic documentation creation, which essentially means that we get our API documented for free with Swagger.
In order to get at least a basic idea of what coding with FastAPI looks like, let’s take a look at a minimal API:
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"}
The preceding few lines of code define a minimal API with a single endpoint (/
) that responds to a GET request with the message “Hello world”
. We instantiate a FastAPI class and use decorators to tell the server which HTTP methods should trigger which function for a response, just like with the Flask microframework, for example.
Python and REST APIs
Python has been used to build REST APIs for a very long time. While there are many options and solutions, DRF and Flask seem to be the most popular ones, at least until recently. If you are feeling adventurous, you can Google less popular or older frameworks such as bottle.py and CherryPy. DRF is a plug-in system for the Django web framework and enables a Django system to create highly customized REST API responses and generate endpoints based on the defined models. DRF is a very mature and battle-tested system. It is regularly updated, and its documentation is very detailed. Flask, Python’s lightweight microframework, is a real gem among the web-building Python tools and can create REST APIs in a lot of different ways. You can use pure Flask and just output the appropriate format (i.e., JSON instead of HTML) or use some of the extensions developed to make the creation of REST APIs as straightforward as possible. Both of these solutions are fundamentally synchronous, although there seems to be active development in the direction of enabling async support.
There are also some very robust and mature tools, such as Tornado, which is an asynchronous networking library (and a server) that is able to scale to tens of thousands of open connections. Finally, in the last couple of years, several new Python-based solutions have been created.
One of these solutions, and arguably the fastest, is Starlette. Dubbed as a lightweight ASGI framework/toolkit, it is ideal for building high-performance async services.
Like Flask was built on top of a couple of solid Python libraries – Werkzeug and Jinja2 – 10 or more years ago, Sebastian Ramirez built FastAPI on top of Starlette and Pydantic, while also adding numerous features and goodies by using the latest Python features, such as type hinting and async support. According to some recent surveys, FastAPI is quickly becoming one of the most popular and most loved web frameworks.. Undeniably, it is gaining in popularity, and it looks like it is here to stay, at least for the foreseeable future.
In Chapter 3, Getting Started with FastAPI, of this book, we will go over the most important features of FastAPI, but at this point, I just want to stress the significance of having a truly async Python framework as the glue for the most diverse components of a system. In fact, besides doing the usual web framework stuff, such as communicating with a database or, in our case, a MongoDB store, spitting out data to a frontend, and managing authentication and authorization, this Python pipeline enables us to quickly integrate and easily achieve frequently required tasks such as background jobs, header and body manipulation, response and request validation, and more through the dependency injection system.
We will try to cover the absolute minimum necessary for you to be able to build a simple FastAPI system. I will make frequent trips to the official documentation site and try to find the simplest solutions. Lastly, we will consider various web server solutions and deployment options (such as Deta, Heroku, and Digitalocean) for our FastAPI Python-based backend, while trying to opt for free solutions.
So, to cut a long story short, we choose FastAPI because we ideally want the ability and speed to handle requests asynchronously as if we were using a Node.js server while having access to the Python ecosystem. Additionally, we want the simplicity and development speed of a framework that automatically generates documentation for us.
After reviewing the backend components, it is time to finalize our stack and put a face on it. We will now look at a minimal introduction to React and discuss what distinguishes it from other (also valid) solutions.