DÍA 08Endpoints de lectura para Sakila · Python Backend y APIs para Datos

Limita y ordena una lista de clientes para que la API no devuelva toda la tabla.

Día 8 20 minIntermedio

Listar clientes con paginación

Objetivos

Vas a responder una lista sin cargar todas las filas y permitir que la persona avance mediante limit y offset acotados.

Concepto

La paginación divide una lista en bloques. limit indica cuántas filas como máximo se devuelven; offset indica cuántas se saltan. Sin límite, un endpoint podría leer cientos o miles de filas en una sola petición. Sin un orden estable, los bloques pueden cambiar de una consulta a otra.

FastAPI valida los parámetros antes de llamar la función. SQLAlchemy añade el límite y el desplazamiento a la consulta. En este ejemplo, customer_id establece un orden reproducible y CustomerPage comunica los valores usados. La paginación no es un filtro de seguridad ni evita compartir información que no debería exponerse: el modelo de respuesta sigue siendo necesario.

Ejemplo

En app/schemas.py, añade un envoltorio para una página debajo de la clase CustomerOut de la lección anterior:

from pydantic import BaseModel
 
class CustomerPage(BaseModel):
    items: list[CustomerOut]
    limit: int
    offset: int

En app/main.py, registra el endpoint:

from typing import Annotated
 
from fastapi import Depends, FastAPI, Query
from sqlalchemy import select
from sqlalchemy.orm import Session
 
from app.database import get_db
from app.models import Customer
from app.schemas import CustomerOut, CustomerPage
 
@app.get("/customers", response_model=CustomerPage)
def list_customers(
    db: Annotated[Session, Depends(get_db)],
    limit: Annotated[int, Query(ge=1, le=50)] = 20,
    offset: Annotated[int, Query(ge=0, le=10000)] = 0,
) -> CustomerPage:
    statement = (
        select(Customer)
        .order_by(Customer.customer_id)
        .limit(limit)
        .offset(offset)
    )
    rows = db.scalars(statement).all()
    return CustomerPage(items=rows, limit=limit, offset=offset)

Una llamada a /customers?limit=10&offset=20 devuelve hasta diez clientes después de saltar los primeros veinte. le=50 evita pedir una página enorme por accidente. El orden es siempre por customer_id, no por el orden interno del motor.

Práctica guiada

  1. Prueba una página de 5 registros y una segunda con offset=5.
  2. Confirma que las claves no se repitan entre las páginas.
  3. Prueba limit=0 y observa que FastAPI devuelve 422 sin consultar la base.

Reto

Agrega un filtro opcional active de tipo booleano. Si no se envía, conserva todos los estados; si se envía, compara con la columna Customer.active.

Intenta el reto antes de consultar las pistas.

Quiz

1. ¿Qué define offset=20?
2. ¿Por qué ordenar antes de paginar?
3. ¿Qué respuesta esperas si limit=0 con ge=1?

Comprobación

La lista ya tiene límite, orden y desplazamiento. La siguiente lección lleva esos mismos controles a los pagos y agrega filtros que no aceptan SQL libre.

TU PROGRESO

Cargando estado…