La paginación es esencial para manejar grandes cantidades de datos en las API, mejorando el rendimiento y la experiencia del usuario. FastAPI facilita la implementación de paginación combinando parámetros de consulta (query parameters) y modelos de datos.
A continuación, te explico cómo implementarla paso a paso:
1. Definición del Modelo de Datos
Usaremos un modelo para representar los datos que queremos paginar.
from typing import List
from pydantic import BaseModel
class Item(BaseModel):
id: int
name: str
description: str
2. Creación de Datos Simulados
Generemos algunos datos simulados para demostrar la paginación.
items = [
{"id": i, "name": f"Item {i}", "description": f"Description for item {i}"}
for i in range(1, 101)
]
3. Configuración de Parámetros de Paginación
Definimos parámetros de consulta (query parameters) como skip (elementos a omitir) y limit (número de elementos a devolver).
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/", response_model=List[Item])
async def get_items(skip: int = Query(0, ge=0), limit: int = Query(10, ge=1)):
return items[skip : skip + limit]
4. Uso del Endpoint
- Solicitud:
GET /items/?skip=10&limit=5
- Respuesta: Los 5 elementos que comienzan desde el índice 10.
[
{
"id": 11,
"name": "Item 11",
"description": "Description for item 11"
},
{
"id": 12,
"name": "Item 12",
"description": "Description for item 12"
},
...
]
5. Respuesta Extendida con Metadatos
Puedes incluir metadatos como el total de elementos o la página actual en la respuesta.
Modelo para la Respuesta
from pydantic import BaseModel
from typing import List, Optional
class PaginatedResponse(BaseModel):
total: int
items: List[Item]
skip: int
limit: int
Actualización del Endpoint
@app.get("/items/", response_model=PaginatedResponse)
async def get_items(skip: int = Query(0, ge=0), limit: int = Query(10, ge=1)):
total = len(items)
paginated_items = items[skip : skip + limit]
return {"total": total, "items": paginated_items, "skip": skip, "limit": limit}
Respuesta del Endpoint
{
"total": 100,
"items": [
{
"id": 11,
"name": "Item 11",
"description": "Description for item 11"
},
{
"id": 12,
"name": "Item 12",
"description": "Description for item 12"
}
],
"skip": 10,
"limit": 2
}
6. Paginación con SQLModel o SQLAlchemy
Si trabajas con una base de datos, puedes implementar paginación usando consultas SQL.
from sqlmodel import Session, select
from fastapi import Depends
from database import get_session # Función que proporciona la sesión de base de datos
@app.get("/items/", response_model=PaginatedResponse)
async def get_items(skip: int = Query(0, ge=0), limit: int = Query(10, ge=1), session: Session = Depends(get_session)):
statement = select(Item).offset(skip).limit(limit)
results = session.exec(statement).all()
total = session.exec(select(Item).count()).scalar()
return {"total": total, "items": results, "skip": skip, "limit": limit}
7. Mejores Prácticas
-
Valores predeterminados razonables: Define un limit por defecto para evitar sobrecargar el servidor.
-
Máximo permitido: Establece un valor máximo para limit si necesitas evitar cargas excesivas.limit: int = Query(10, ge=1, le=100)
-
Filtros adicionales: Agrega parámetros de consulta para buscar o filtrar los datos.
Conclusión
La implementación de paginación en FastAPI es directa, ya sea con datos simulados o bases de datos. Aprovecha los modelos de Pydantic para estructurar las respuestas y las consultas SQL para optimizar el rendimiento en bases de datos.