python
41 lines · 7 steps
Building a users router in FastAPI
A FastAPI router pairs Pydantic response models with SQLAlchemy queries to serve validated, shape-controlled JSON.
Explained by
highlit
1from datetime import datetime
2from fastapi import APIRouter, Depends, HTTPException, status
3from pydantic import BaseModel, ConfigDict, EmailStr
4from sqlalchemy.orm import Session
5
6from .database import get_session
7from .models import User
8
9router = APIRouter(prefix="/users", tags=["users"])
10
11
12class ProfileOut(BaseModel):
13 model_config = ConfigDict(from_attributes=True)
14
15 id: int
16 username: str
17 email: EmailStr
18 full_name: str | None = None
19 is_verified: bool
20 created_at: datetime
21
22
23class UserListItem(BaseModel):
24 model_config = ConfigDict(from_attributes=True)
25
26 id: int
27 username: str
28 is_verified: bool
29
30
31@router.get("", response_model=list[UserListItem])
32def list_users(session: Session = Depends(get_session)):
33 return session.query(User).order_by(User.username).all()
34
35
36@router.get("/{user_id}", response_model=ProfileOut)
37def get_user(user_id: int, session: Session = Depends(get_session)):
38 user = session.get(User, user_id)
39 if user is None:
40 raise HTTPException(status.HTTP_404_NOT_FOUND, detail="User not found")
41 return user
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Separate response models let each endpoint expose exactly the fields it should, hiding sensitive columns like email from list views.
- 2from_attributes lets Pydantic read ORM objects directly, so you can return SQLAlchemy models and FastAPI serializes them for you.
- 3Depends injects a database session per request, keeping route functions free of setup and teardown boilerplate.
Related explainers
java
@Service public class OrderCheckoutService { private final OrderRepository orderRepository;
How @Transactional guards a Spring checkout
dependency-injection
transactions
atomicity
Intermediate
6 steps
python
import json from dataclasses import dataclass, field, asdict from datetime import datetime from typing import Any
JSON round-tripping with Python dataclasses
dataclasses
serialization
json
Intermediate
6 steps
typescript
import { Injectable } from '@angular/core'; import { PreloadingStrategy, Route, Routes, RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { Observable, of, timer } from 'rxjs';
A custom preloading strategy in Angular
lazy-loading
preloading
rxjs
Intermediate
7 steps
java
@Service public class OrderMetricsService { private final MeterRegistry registry;
Instrumenting orders with Micrometer in Spring
metrics
micrometer
observability
Intermediate
8 steps
rust
use std::fs::File; use std::io::{self, BufWriter}; use std::path::Path;
Serializing config to JSON in Rust
serialization
serde
file-io
Intermediate
7 steps
python
import re from django.core.exceptions import ValidationError from django.core.validators import RegexValidator
Building a deconstructible validator in Django
validation
regex
deconstructible
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/building-a-users-router-in-fastapi-explained-python-9752/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.