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!