how-to-build-scalable-apis-with-fastapi-and-postgresql.html

How to Build Scalable APIs with FastAPI and PostgreSQL

In today's digital landscape, building scalable APIs is essential for the success of modern applications. FastAPI, a modern web framework for building APIs with Python, offers high performance and ease of use, while PostgreSQL serves as a powerful relational database. Together, they create a robust solution for developing scalable and efficient APIs. In this article, we’ll explore how to leverage FastAPI and PostgreSQL to build APIs that can handle high traffic and large datasets effectively.

What is FastAPI?

FastAPI is a web framework designed for building APIs quickly and efficiently. It is built on top of standard Python type hints, which allows for automatic data validation, serialization, and interactive API documentation using Swagger UI. Here are some of its key features:

  • Fast performance: Based on Starlette for the web parts and Pydantic for the data parts, FastAPI is one of the fastest frameworks available.
  • Automatic validation: Utilizes Python’s type hints to validate request data automatically.
  • Interactive documentation: Generates interactive API documentation using Swagger UI and ReDoc.

What is PostgreSQL?

PostgreSQL is a powerful, open-source object-relational database system known for its advanced features and reliability. It supports complex queries and offers robust data integrity. Key features include:

  • ACID compliance: Ensures reliable transactions.
  • Extensibility: Allows users to define their own data types and functions.
  • Concurrency support: Handles multiple transactions at once without locking.

Use Cases for FastAPI and PostgreSQL

The combination of FastAPI and PostgreSQL is perfect for various applications, including:

  • Microservices architecture: FastAPI's lightweight design makes it ideal for microservices.
  • Web applications: Building RESTful APIs for frontend frameworks like React or Vue.js.
  • Data-driven applications: Applications that require complex data manipulations and querying.

Setting Up Your Environment

Before diving into coding, ensure you have Python, FastAPI, and PostgreSQL installed. You can set up your environment using:

# Install FastAPI and an ASGI server (e.g., uvicorn)
pip install fastapi uvicorn

# Install PostgreSQL driver for Python
pip install asyncpg[postgresql]

# Install SQLAlchemy for ORM
pip install sqlalchemy

Creating a Scalable API with FastAPI and PostgreSQL

Step 1: Setting Up the Database

First, create a PostgreSQL database. You can do this via the psql command line:

CREATE DATABASE fastapi_db;

Next, define a table for storing user information:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE NOT NULL
);

Step 2: Defining Your FastAPI Application

Create a new Python file, main.py, and set up your FastAPI application:

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

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

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

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    email = Column(String, unique=True, index=True)

Base.metadata.create_all(bind=engine)

app = FastAPI()

Step 3: Creating CRUD Operations

Next, let’s implement the Create, Read, Update, and Delete (CRUD) operations. Add the following endpoints to your main.py:

from fastapi import Depends
from sqlalchemy.orm import Session

# Dependency to get a database session
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# Create a new user
@app.post("/users/", response_model=User)
def create_user(user: User, db: Session = Depends(get_db)):
    db.add(user)
    db.commit()
    db.refresh(user)
    return user

# Read all users
@app.get("/users/", response_model=list[User])
def read_users(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
    users = db.query(User).offset(skip).limit(limit).all()
    return users

# Update a user
@app.put("/users/{user_id}", response_model=User)
def update_user(user_id: int, user: User, db: Session = Depends(get_db)):
    db_user = db.query(User).filter(User.id == user_id).first()
    if not db_user:
        raise HTTPException(status_code=404, detail="User not found")
    db_user.name = user.name
    db_user.email = user.email
    db.commit()
    db.refresh(db_user)
    return db_user

# Delete a user
@app.delete("/users/{user_id}")
def delete_user(user_id: int, db: Session = Depends(get_db)):
    db_user = db.query(User).filter(User.id == user_id).first()
    if not db_user:
        raise HTTPException(status_code=404, detail="User not found")
    db.delete(db_user)
    db.commit()
    return {"detail": "User deleted"}

Step 4: Running Your Application

Finally, run your FastAPI application using Uvicorn:

uvicorn main:app --reload

You can now visit http://127.0.0.1:8000/docs to see the interactive API documentation and test your endpoints.

Conclusion

Building scalable APIs with FastAPI and PostgreSQL is not only efficient but also allows developers to create robust applications that can handle high loads. With FastAPI's automatic validation and PostgreSQL's powerful querying capabilities, you can build APIs that are both scalable and easy to maintain. By following the steps outlined in this article, you’ll be well on your way to creating a high-performance API that meets the demands of modern applications.

Start experimenting with additional features such as authentication, rate limiting, and caching to further enhance your API’s scalability and performance!

SR
Syed
Rizwan

About the Author

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