2-how-to-build-restful-apis-using-fastapi-and-postgresql.html

How to Build RESTful APIs Using FastAPI and PostgreSQL

Creating RESTful APIs is essential in modern web development, enabling seamless communication between client and server applications. FastAPI, a modern web framework for building APIs with Python, is known for its speed and simplicity. Coupled with PostgreSQL, a powerful open-source relational database, you can create robust and scalable APIs efficiently. In this article, we’ll explore how to build a RESTful API using FastAPI and PostgreSQL, providing detailed coding examples and actionable insights.

What is FastAPI?

FastAPI is a Python web framework designed for building APIs quickly and efficiently. Its key features include:

  • Performance: FastAPI is one of the fastest Python frameworks, thanks to its asynchronous capabilities.
  • Automatic Documentation: It generates interactive API documentation using Swagger UI and ReDoc.
  • Data Validation: FastAPI leverages Pydantic for data validation, ensuring your API receives and processes data correctly.

Why Use PostgreSQL?

PostgreSQL is a highly advanced, open-source relational database management system that supports SQL and many modern programming constructs. Here’s why it’s a great choice for your API:

  • Reliability: PostgreSQL is known for its robustness and data integrity.
  • Performance: It handles large volumes of data and complex queries efficiently.
  • Extensibility: PostgreSQL supports custom functions, data types, and operators.

Setting Up Your Environment

Before diving into code, you need to set up your environment. Here’s what you’ll need:

  1. Python: Ensure you have Python 3.7 or later installed.
  2. FastAPI: Install FastAPI and Uvicorn (an ASGI server) using pip: bash pip install fastapi uvicorn
  3. PostgreSQL: Install PostgreSQL and set up a database. You can use tools like pgAdmin for ease of use.
  4. SQLAlchemy: Use SQLAlchemy as an ORM (Object Relational Mapper) to interact with your database: bash pip install sqlalchemy psycopg2

Creating Your FastAPI Application

Step 1: Project Structure

Create a project folder and set up the following structure:

/fastapi_postgres
│
├── app.py
├── models.py
├── database.py
└── schemas.py

Step 2: Database Connection

In database.py, establish a connection to your PostgreSQL database:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

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

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

Step 3: Define Your Models

Create models.py to define your database models. Here’s an example of a simple Item model:

from sqlalchemy import Column, Integer, String
from database import Base

class Item(Base):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String, index=True)

Step 4: Create Pydantic Schemas

In schemas.py, define Pydantic schemas for data validation:

from pydantic import BaseModel

class ItemBase(BaseModel):
    name: str
    description: str

class ItemCreate(ItemBase):
    pass

class Item(ItemBase):
    id: int

    class Config:
        orm_mode = True

Step 5: Building the API

Now, let’s implement CRUD operations in app.py:

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from database import SessionLocal, engine
import models, schemas

models.Base.metadata.create_all(bind=engine)

app = FastAPI()

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/items/", response_model=schemas.Item)
def create_item(item: schemas.ItemCreate, db: Session = Depends(get_db)):
    db_item = models.Item(name=item.name, description=item.description)
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item

@app.get("/items/{item_id}", response_model=schemas.Item)
def read_item(item_id: int, db: Session = Depends(get_db)):
    db_item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return db_item

@app.put("/items/{item_id}", response_model=schemas.Item)
def update_item(item_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)):
    db_item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    db_item.name = item.name
    db_item.description = item.description
    db.commit()
    db.refresh(db_item)
    return db_item

@app.delete("/items/{item_id}")
def delete_item(item_id: int, db: Session = Depends(get_db)):
    db_item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    db.delete(db_item)
    db.commit()
    return {"detail": "Item deleted"}

Step 6: Running Your Application

To run your FastAPI application, execute the following command in your terminal:

uvicorn app:app --reload

Visit http://127.0.0.1:8000/docs to explore the interactive API documentation generated by FastAPI.

Conclusion

Building RESTful APIs using FastAPI and PostgreSQL is a straightforward process that can significantly enhance your web applications. With FastAPI's speed and PostgreSQL's reliability, you can create high-performance APIs that are easy to maintain and scale.

Key Takeaways

  • FastAPI allows for rapid API development with automatic documentation and data validation.
  • PostgreSQL provides a robust and scalable database solution.
  • With a clear project structure and organized code, maintaining and extending your API becomes easier.

By following the steps outlined in this article, you can successfully create a RESTful API that meets your application’s 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.