Write your first RESTful API in FastAPI

Write your first RESTful API in FastAPI

FastAPI example

A REST API is an API that conforms to the constrains of REST architecture and style. REST stands for representational state transfer. It was created by Roy Fielding. The cool thing about REST APIs is that they're cacheable, stateless and consistent. You can read more about it here. A simple way to look at an API is viewing it as an interpreter between the computer resources, or web services and a client, or user. It's also a way for organizations to share information securely. Say you want to get the ten most rated movies from IMDB. IMDB can share this information to you through an API, without disclosing sensitive information. Check out the imdb API.

Today we'll use FastAPI framework to build our first web API. FastAPI is written in Python, and is just one of the python web frameworks. Two of the more known python frameworks would be Django and Flask.

Let's get to it!

What we'll cover:

Prerequisites

If you just want to read, then you can just follow along. If you want to code along, here's what we're going to need:

  • Python installed on your machine. If you're on linux, it's already installed :)
  • A virtual environment. It's not required, but it's good practice. Run the following command to install:
    sudo apt install python3-pip && sudo pip3 install virtualenv
    
    • A code editor. I'm using VS Code. You can download it here. You'll need the python extension for more productivity. Just click on the Extensions > Search 'Python', and ensure you install the Microsoft's version.

image.png

What is FastAPI?

FastAPI is a high performance, easy to learn, fast to code, ready for production python framework. It first showed up in 2019, created by Sebastian Ramírez. It improves the deveoper experience by having self-documenting APIs, and at the same time reduces boilerpate code.

Hello World in FastAPI

Let's see how easy it is to use FastAPI:

image.png

Here's what I've done:

  1. from fastapi import FastAPI imports the FastAPI
  2. app = FastAPI() creates an instance of fastapi for us to use
  3. @app.get("/") is a decorator that uses the http get method from FastAPI.
  4. def index() <- Here we define a method that returns a hello world message

FastAPI basics

Most important things to understand while working with FastAPI:

  • Typehints

image.png Although typehints are built into python, they're crucial when working with FastAPI. As you can see in the example above, you will need to explicitely define the data type for all your variables ie: name: str. This will apply for all data types say str, int, list, dict etc.

  • Path and Path Parameters

image.png The "/books" inside the parenthesis is a path. This means that when user goes to the path say example.com/books, they will be accessing this "/books" resource path

image.png The "{book_id}" is called a path parameter. Path parameters are enclosed inside of curly braces {}. They offer a way to control specific resources. Say for instance you want to get a specific book, then you might want to add a path parameter with that book's id.

  • Query Parameters image.png These are not required. All parameters outside of the path are considered as query parameters. Note the start: int and end: int on the all_read_books function. Those are the two query parameters that our API will expect. The query is represented in a key-value pair, comes after a question mark ? and is separated by an ampersand &. In our case, the query would be something similar to https://example.com/books/?start=0&end=12

  • Request Body image.png

A request body is what the client will send to our API. In our example, we've created a Book class, and parsed it to the add_a_book function as a book parameter. This will send an instance of a Book with the post method to our API.

Build a working API

Now let's build a working API in FastAPI:

  • Create an empty directory anywhere:
    mkdir fastapi && cd fastapi
    
  • Create a virtual environment and activate it:
    virtualenv venv && source venv/bin/activate
    
  • Install FastAPI:
    pip install fastapi uvicorn
    
  • Now open the in your editor:

    code .
    
  • Let's write our first endpoint! Get all books. Copy the code below:

from fastapi import FastAPI

app = FastAPI()

db = []

@app.get("/books")
def get_all_books():
    return db

Line 3 creates an empty list to act as our in-memory data storage. the /books path will return whatever is inside the db. Save the file as main.py (This is important)

  • To view it, go back to the terminal window and run the following command:
    uvicorn main:app --reload
    

This calls the app variable inside of the main.py script. The --reload ensures that the server will refresh each time we save the file. Now head over to localhost:8000/books

You should see something similar to this:

image.png

  • Add a book to our db:

First we'll need a Book. For that, we'll create a Book class to act as our Response Model. Import BaseModel:

from pydantic import BaseModel

Add the Book class and add_a_book function:

class Book(BaseModel):
    title: str

@app.post("/books")
def add_a_book(book: Book):
    return db.append(book)

Here, we send the book request (Our book title) to the API.

  • Delete a Book from db:
    To delete a book, we'll just use an ordinary pop() method
    Notice we're using book_id as a path parameter:
@app.delete("/books/{book_id}")
def delete_a_book(book_id: int):
    return db.pop(book_id)
  • Get a specific Book To get one book, we'll need the book's id on the list. Here's how to do it:

@app.get("/books/{book_id}")
def get_a_book(book_id: int):
    return db[book_id]

Here we use the list index as our book_id and parse it as our path parameter.

Get entire code on my Github or BitBucket repo.

Swagger UI

To test out our API, we'll use the inbuilt documentation for FastAPI. Head over to your browser and open the link http://localhost:8000/docs. You should be greeted by this page:

image.png

Let's test the methods:

  • Expand Get All Books, click try it out then Excecute: image.png

  • We'll do the same for Add A Book: image.png Add several books so that we have something to test with. As you can see, I've added four:

image.png

  • Get A Book, it requires us to enter a book_id, and returns a book in that index in our db

image.png

  • Delete A Book is similar to Get A Book

image.png