Standard patterns for building and maintaining CRUD APIs with FastAPI and SQLModel: models, routers, database access, and error handling in a reusable way.
Use this Skill whenever you are:
This Skill must work for any FastAPI + SQLModel project, not just a single repository.
db.py or similar: session creation and engine.models.py or models/: SQLModel models.routers/ or routes/: FastAPI routers per resource.main.py: FastAPI app entrypoint registering routers.The exact filenames can differ between projects; the patterns stay the same.
Each logical resource (e.g. Task, Item, User) should have its
own router module, for example:
routers/tasks.py with a APIRouter(prefix="/tasks", tags=["tasks"]).Typical REST endpoints per resource:
GET /<resource> → list items.POST /<resource> → create item.GET /<resource>/{id} → get single item.PUT /<resource>/{id} → replace item.PATCH /<resource>/{id} → partial update (optional).DELETE /<resource>/{id} → delete item. [web:53][web:59]Resource names should be plural in paths (/tasks, /users), with
singular nouns used in model/type names (Task, User).
Use SQLModel models for database tables, with:
id or similar).created_at, updated_at) when useful.nullable, max_length).When needed, define separate Pydantic/SQLModel schemas for:
TaskCreate) – fields required for creation.TaskUpdate) – optional fields for partial updates.TaskRead) – what the API returns.Avoid exposing internal-only fields (e.g. secrets) in response models.
Provide a shared dependency for DB sessions, for example:
get_session() in db.py that yields a Session object.Use Depends(get_session) in routers to access the database.
Do not create database engines or sessions directly inside routers or endpoint functions. Keep connection logic centralized. [web:53][web:57]
For each resource, the default CRUD behaviour should follow this pattern:
Create (POST):
List (GET collection):
Get (GET single):
HTTPException(status_code=404) with a clear
message.Update (PUT/PATCH):
Delete (DELETE):
Never let database or Python exceptions leak directly to clients.
Use HTTPException with appropriate status codes and simple, safe
error messages. [web:53][web:59]
Common error cases:
Log details server-side if needed, but keep responses simple.
Always declare response models in router decorators when practical:
response_model=TaskRead or List[TaskRead].This improves:
Avoid returning raw dicts or mixing data shapes; keep responses consistent.
When adding filtering/sorting:
status, sort_by, order).For pagination:
limit and offset or page/size pairs.When present, this Skill should align with:
db.py or equivalent – engine and get_session dependency.models.py or models/ – SQLModel models for resources.routers/ or routes/ – resource-specific routers.If these files are missing, propose creating them using these patterns rather than inventing a new, ad-hoc CRUD style for each resource.