Project: REST CRUD API
Introduction
This project builds a complete Items API under /api/v1/items—list with pagination, create, read, update, and delete. You combine Pydantic schemas, SQLAlchemy, Alembic, and pytest into one cohesive service you can extend or deploy. OpenAPI docs at /docs let you test without Postman.
Prerequisites
- SQLAlchemy With FastAPI
- Alembic Database Migrations
- APIRouter and Project Structure
- Testing FastAPI Applications
Project Goals
GET /api/v1/items/— paginated list with optional searchPOST /api/v1/items/— create item (201)GET /api/v1/items/{id}— detail or 404PATCH /api/v1/items/{id}— partial updateDELETE /api/v1/items/{id}— 204 delete- pytest covers happy path and 404
Step 1: Project Layout
Wire router in main.py:
from app.api.v1.api import api_router
app.include_router(api_router, prefix="/api/v1")Step 2: Schema and Model
schemas/item.py — ItemCreate, ItemUpdate, ItemRead (from Pydantic chapter).
models/item.py — Item with id, name, price, created_at.
Run:
alembic revision --autogenerate -m "Create items"
alembic upgrade headStep 3: List With Pagination and Filter
endpoints/items.py:
Test search: GET /api/v1/items/?q=phone&limit=5
Step 4: CRUD Endpoints
Implement POST, GET /{id}, PATCH, DELETE using patterns from SQLAlchemy chapter.
Return HTTPException(404) when db.get(Item, id) is None.
Step 5: OpenAPI Verification
Start server:
uvicorn app.main:app --reloadOpen http://127.0.0.1:8000/docs:
- Expand items tag
- Try POST with JSON body
- Confirm 422 when
priceis negative
See OpenAPI chapter.
Step 6: pytest
tests/test_items.py:
Use conftest.py from testing chapter.
Step 7: Optional Enhancements
- Sort query param:
sort=price,order=desc - Response envelope
{code, message, data} - Admin-only
DELETEwith JWT—add in next project
Verification Checklist
- All CRUD routes work via
/docs - Pagination respects
limitmax - Alembic migration applied on fresh DB
-
pytestgreen - No secrets in repo
FAQ
Trailing slash 307 redirect?
Be consistent—use /items/ in tests and docs.
ilike on SQLite?
Works in SQLAlchemy; MySQL uses LIKE case sensitivity per collation.
Export OpenAPI for frontend?
curl /openapi.json — see OpenAPI chapter.
Add auth to POST?
Next project—Todo API with auth.