2-how-to-build-a-restful-api-with-fastapi-and-postgresql.html

How to Build a RESTful API with FastAPI and PostgreSQL

In today's fast-paced digital world, building efficient and scalable APIs is crucial for modern web applications. FastAPI has emerged as one of the go-to frameworks for creating RESTful APIs due to its speed, simplicity, and automatic generation of interactive documentation. When combined with PostgreSQL—a powerful and reliable relational database—developers can create robust applications that handle complex data with ease. This article will guide you through building a RESTful API using FastAPI and PostgreSQL, complete with code examples and actionable insights.

What is FastAPI?

FastAPI is a modern web framework for building APIs with Python 3.6+ based on standard Python type hints. It allows developers to create APIs quickly and efficiently while ensuring high performance. Some of its key features include:

  • Automatic validation: FastAPI automatically checks the data types of incoming requests using Python type hints.
  • Interactive API documentation: It generates interactive Swagger UI and ReDoc documentation.
  • Asynchronous support: FastAPI is built on top of Starlette, providing support for asynchronous programming.

Why Use PostgreSQL?

PostgreSQL is an advanced open-source relational database known for its robustness and scalability. It offers features such as:

  • ACID compliance: Ensures reliable transactions.
  • Rich data types: Supports JSON, arrays, and more.
  • Extensibility: Allows for custom data types and functions.

Combining FastAPI with PostgreSQL gives you the best of both worlds: a high-performance API and a powerful database.

Prerequisites

Before we dive into the code, ensure you have the following installed:

  • Python 3.6 or higher
  • PostgreSQL
  • pip for installing Python packages

You'll also need to install the following libraries:

pip install fastapi[all] sqlalchemy psycopg2
  • fastapi[all]: Installs FastAPI along with all dependencies.
  • sqlalchemy: For ORM support with PostgreSQL.
  • psycopg2: PostgreSQL adapter for Python.

Step-by-Step Guide to Building a RESTful API

Step 1: Set Up the Database

Start by creating a PostgreSQL database. You can do this using the PostgreSQL command line:

CREATE DATABASE fastapi_db;

Next, create a table to store data. Here’s an example SQL command to create a simple items table:

CREATE TABLE items (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    price NUMERIC(10, 2) NOT NULL
);

Step 2: Create the FastAPI Application

Now, let’s start building our FastAPI application.

Creating the main application file

Create a new file named main.py and add the following code:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy import create_engine, Column, Integer, String, Numeric
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql://username:password@localhost/fastapi_db"

engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

app = FastAPI()

Make sure to replace username and password with your PostgreSQL credentials.

Step 3: Define the Data Model

Using SQLAlchemy, create a model to represent the items table:

class Item(Base):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String)
    price = Column(Numeric(10, 2))

Base.metadata.create_all(bind=engine)

Step 4: Create Pydantic Schemas

Define Pydantic models to validate request and response data:

class ItemCreate(BaseModel):
    name: str
    description: str
    price: float

class ItemResponse(ItemCreate):
    id: int

    class Config:
        orm_mode = True

Step 5: Implement CRUD Operations

Now, let’s implement the basic CRUD operations.

Create an Item

@app.post("/items/", response_model=ItemResponse)
def create_item(item: ItemCreate):
    db = SessionLocal()
    db_item = Item(name=item.name, description=item.description, price=item.price)
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    db.close()
    return db_item

Read All Items

@app.get("/items/", response_model=list[ItemResponse])
def read_items():
    db = SessionLocal()
    items = db.query(Item).all()
    db.close()
    return items

Read a Single Item

@app.get("/items/{item_id}", response_model=ItemResponse)
def read_item(item_id: int):
    db = SessionLocal()
    item = db.query(Item).filter(Item.id == item_id).first()
    db.close()
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

Update an Item

@app.put("/items/{item_id}", response_model=ItemResponse)
def update_item(item_id: int, item: ItemCreate):
    db = SessionLocal()
    db_item = db.query(Item).filter(Item.id == item_id).first()
    if db_item is None:
        db.close()
        raise HTTPException(status_code=404, detail="Item not found")

    db_item.name = item.name
    db_item.description = item.description
    db_item.price = item.price
    db.commit()
    db.refresh(db_item)
    db.close()
    return db_item

Delete an Item

@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    db = SessionLocal()
    db_item = db.query(Item).filter(Item.id == item_id).first()
    if db_item is None:
        db.close()
        raise HTTPException(status_code=404, detail="Item not found")

    db.delete(db_item)
    db.commit()
    db.close()
    return {"detail": "Item deleted"}

Step 6: Run the Application

Finally, run your FastAPI application using Uvicorn:

uvicorn main:app --reload

Visit http://127.0.0.1:8000/docs in your web browser to see the interactive API documentation generated by FastAPI.

Conclusion

Building a RESTful API with FastAPI and PostgreSQL is a straightforward process that can significantly enhance your web applications. With FastAPI's speed and ease of use combined with PostgreSQL's reliability, you can create efficient and scalable APIs in no time. This guide has covered the essential steps, from setting up your database to implementing CRUD operations. Now it's time to experiment, optimize, and expand upon your API to fit your specific needs! Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.