Skip to main content

Capstone Project - Blog Posts API

Problem Statement In this capstone project, you will develop a REST API to manage blog posts. Each blog post contains:
  • ID
  • Title
  • Description
  • Author
  • Created At
The application should support the following operations:
  • Create a Post
  • View All Posts
  • View a Post
  • Update a Post
  • Delete a Post
By the end of this project, you will have a complete backend application that demonstrates core practices for building REST APIs using FastAPI and SQLAlchemy.

Learning Objectives

After completing this project, you will be able to:
  • Build RESTful APIs using FastAPI.
  • Organize applications using a modular project structure.
  • Configure SQLite with SQLAlchemy ORM.
  • Design database models using SQLAlchemy.
  • Validate requests and responses using Pydantic Schemas.
  • Implement database session dependencies.
  • Handle data persistence using CRUD routines.
  • Manage database schema changes using Alembic migrations.
  • Migrate database engines from SQLite to PostgreSQL.

Step 1: Create the Project

Objective Create a new project directory and prepare the development environment. Instructions
  • Create a new project directory named blog-api.
  • Navigate to the project directory.
  • Initialize the project using uv.
Task Initialize the project using uv.
Run & Verify Verify that:
  • The project directory has been created.
  • A pyproject.toml file has been generated.

Step 2: Create a Virtual Environment

Objective Initialize and activate a virtual environment to isolate project dependencies. Instructions
  • Create the virtual environment using uv venv.
  • Activate the virtual environment based on your operating system.
Task Initialize and activate the virtual environment.
Create the virtual environment
Activate the virtual environmentFor Windows:
For macOS / Linux:
Run & Verify Verify that:
  • The virtual environment folder .venv is created.
  • The command prompt is updated, indicating the virtual environment is active.

Step 3: Install Required Packages

Objective Install all the libraries required to build the Blog Posts API. Instructions
  • Install fastapi, uvicorn[standard], and sqlalchemy using uv.
Task Install all required dependencies.
Run & Verify Verify that:
  • All packages are installed successfully.
  • The pyproject.toml file contains the installed dependencies.

Step 4: Create the Project Structure

Objective Organize the application into a modular structure to separate concerns. Instructions
  • Create the following folder structure to house files like API routes, models, schemas, and helpers.
Task Design the project folder structure.
Run & Verify Verify that:
  • The app/ folder is initialized.
  • Subdirectories and placeholders for modular code are created.

Step 5: Configure the Database

Objective Configure SQLAlchemy so the application can communicate with the database. Instructions
  • Define the DATABASE_URL to point to a SQLite file named blog.db.
  • Initialize the SQLAlchemy engine and configure the Session factory.
  • Define the Declarative Base class Base.
Task Configure database connection and SQLAlchemy base.
File: app/database.py
Run & Verify Verify that:
  • The database module compiles cleanly.
  • SessionLocal is set up to issue database connections.

Step 6: Create the Blog ORM Model

Objective Define the structure of the posts table using a SQLAlchemy model class. Instructions
  • Create a Post class in app/models.py that inherits from Base.
  • Declare Mapped types for columns: id, title, description, author, and created_at.
Task Implement the Post SQLAlchemy model.
File: app/models.py
Run & Verify Verify that:
  • Column types map appropriately to target values (e.g. String(200) and Text).
  • The imports reference the database base configuration module correctly.

Step 7: Create the Database Tables

Objective Generate the SQLite database and create the posts table during application startup. Instructions
  • Set up app/main.py.
  • Import the database metadata and initialize the tables using Base.metadata.create_all.
Task Initialize database tables in main.py.
File: app/main.py
Run & Verify
  • Start the application using:
  • Confirm that blog.db has been created in your root workspace folder and contains the posts table.

Step 8: Create the Pydantic Schemas

Objective Define data schemas using Pydantic models to validate API requests and serialize responses. Instructions
  • Define PostBase with common attributes.
  • Inherit from it to create PostRequest and PostResponse schemas.
  • Turn on from_attributes inside response models for direct ORM serialization.
Task Create the validation schemas using Pydantic inheritance.
File: app/schemas.py
Run & Verify Verify that:
  • The schema schemas are correctly configured.
  • from_attributes matches compatibility rules for SQLAlchemy queries.

Step 9: Implement the Database Dependency

Objective Expose a reusable database session dependency that manages session lifecycles automatically. Instructions
  • Create app/dependencies.py.
  • Implement get_db yielding a database session and safely closing it when finished.
Task Create the get_db dependency.
File: app/dependencies.py
Run & Verify Verify that:
  • The generator function closes connections even if an exception occurs during request execution.

Step 10: Implement the CRUD Layer

Objective Write standard data access functions using SQLAlchemy ORM queries for the posts. Instructions
  • Define functions for: creating, updating, retrieving (all/single), and deleting posts.
  • Use the modern SQLAlchemy 2.0 select statement for reading queries.
Task Implement the CRUD utilities.
File: app/crud.py
Run & Verify Verify that:
  • All functions compile without syntax errors.
  • Query statements call correct filter rules.

Step 11: Register the Router

Objective Create the router layer endpoints and link it to the main FastAPI application. Instructions
  • Build API endpoint handlers in app/api/posts.py using APIRouter.
  • Use modern Annotated syntax to inject database sessions.
  • Mount the router on the FastAPI application instance in app/main.py.
Task Implement and mount the API router.
File: app/api/posts.py
File: app/main.py
Run & Verify Verify that:
  • Endpoint handlers map correctly to HTTP verbs.
  • Routing endpoints return expected status codes.

Step 12: Run & Verify the APIs

Objective Validate the REST API endpoints using the interactive documentation page. Instructions
  • Start the application server.
  • Navigate to the Swagger UI page in your browser.
  • Perform tests for all HTTP operations.
Task Run testing requests against endpoint routes.
Start the server:
Open interactive docs page:
Verify following payloadsPOST Request Body:
PUT Request Body:
Run & Verify Confirm that:
  • POST requests yield HTTP 200 with auto-generated id.
  • Invalid requests (e.g. referencing a missing ID) yield HTTP 404.

Step 13: Configure Alembic

Objective Initialize Alembic migration environment to track future database changes. Instructions
  • Install alembic package.
  • Initialize migration files layout.
  • Bind the engine configuration URL and project Base model metadata inside Alembic scripts.
Task Setup Alembic configuration layout.
Install Alembic package:
Initialize Alembic folders:
File: alembic.ini
File: alembic/env.py
Run & Verify Verify that:
  • Alembic successfully reads target metadata configuration.
  • The alembic subdirectory and its files are initialized.

Step 14: Create Database Migrations

Objective Generate database migrations scripts and upgrade the SQLite structure. Instructions
  • Use revision --autogenerate to compare model metadata against SQLite file.
  • Perform upgrade to sync the database version.
Task Perform database schema migrations.
Generate migration version script:
Apply migrations:
Run & Verify Verify that:
  • Version files are added to alembic/versions/.
  • alembic_version tracking table is created inside SQLite database.

Step 15: Switch to PostgreSQL

Objective Transition the database system settings from SQLite to PostgreSQL engine. Instructions
  • Add psycopg binary database driver.
  • Adjust DATABASE_URL configurations.
  • Update settings in both app/database.py and alembic.ini.
Task Configure PostgreSQL driver and run target migrations.
Install driver:
File: app/database.py
File: alembic.ini
Sync database scheme:
Run & Verify Confirm that:
  • PostgreSQL connects without errors.
  • Alembic tables are created on the target PostgreSQL server instance.