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

Project Goals

  • GET /api/v1/items/ — paginated list with optional search
  • POST /api/v1/items/ — create item (201)
  • GET /api/v1/items/{id} — detail or 404
  • PATCH /api/v1/items/{id} — partial update
  • DELETE /api/v1/items/{id} — 204 delete
  • pytest covers happy path and 404

Step 1: Project Layout

Wire router in main.py:

python
from app.api.v1.api import api_router
 
app.include_router(api_router, prefix="/api/v1")

Step 2: Schema and Model

schemas/item.pyItemCreate, ItemUpdate, ItemRead (from Pydantic chapter).

models/item.pyItem with id, name, price, created_at.

Run:

bash
alembic revision --autogenerate -m "Create items"
alembic upgrade head

Step 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:

bash
uvicorn app.main:app --reload

Open http://127.0.0.1:8000/docs:

  • Expand items tag
  • Try POST with JSON body
  • Confirm 422 when price is 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 DELETE with JWT—add in next project

Verification Checklist

  • All CRUD routes work via /docs
  • Pagination respects limit max
  • Alembic migration applied on fresh DB
  • pytest green
  • 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.

Deploy?

Production deployment project.