Crear y usar APIRouter básico
Cuando una aplicación FastAPI comienza a crecer, el archivo principal puede volverse difícil de mantener. APIRouter es la solución que FastAPI proporciona para dividir las rutas en módulos separados, manteniendo el código organizado y fácil de gestionar.
Un APIRouter funciona de manera similar a la instancia principal de FastAPI, pero está diseñado para ser incluido en la aplicación principal. Permite definir rutas, middleware y dependencias de forma modular, facilitando el desarrollo en equipo y la escalabilidad del proyecto.
Creación de un APIRouter básico
Para crear un APIRouter, simplemente importamos la clase desde FastAPI y creamos una instancia:
from fastapi import APIRouter
# Crear una instancia de APIRouter
router = APIRouter()
# Definir rutas usando el router
@router.get("/usuarios")
async def obtener_usuarios():
return {"usuarios": ["Ana", "Carlos", "María"]}
@router.post("/usuarios")
async def crear_usuario(nombre: str):
return {"mensaje": f"Usuario {nombre} creado correctamente"}
El router se comporta exactamente igual que la instancia principal de FastAPI. Podemos usar todos los decoradores HTTP (@router.get()
, @router.post()
, @router.put()
, etc.) y las mismas funcionalidades de validación y documentación.
Integración con la aplicación principal
Una vez definido el router, necesitamos incluirlo en nuestra aplicación principal usando el método include_router()
:
from fastapi import FastAPI
from fastapi import APIRouter
# Crear la aplicación principal
app = FastAPI()
# Crear el router
usuarios_router = APIRouter()
@usuarios_router.get("/usuarios")
async def obtener_usuarios():
return {"usuarios": ["Ana", "Carlos", "María"]}
@usuarios_router.post("/usuarios")
async def crear_usuario(nombre: str):
return {"mensaje": f"Usuario {nombre} creado correctamente"}
# Incluir el router en la aplicación principal
app.include_router(usuarios_router)
Con esta configuración, las rutas definidas en el router estarán disponibles en la aplicación principal. La ruta /usuarios
funcionará exactamente igual que si la hubiéramos definido directamente en app
.
Configuración de prefijos y etiquetas
Los routers permiten configurar prefijos para agrupar rutas relacionadas y etiquetas para organizar la documentación automática:
from fastapi import FastAPI, APIRouter
app = FastAPI()
# Router con prefijo y etiquetas
productos_router = APIRouter(
prefix="/api/v1",
tags=["productos"]
)
@productos_router.get("/productos")
async def listar_productos():
return {"productos": ["Laptop", "Mouse", "Teclado"]}
@productos_router.get("/productos/{producto_id}")
async def obtener_producto(producto_id: int):
return {"id": producto_id, "nombre": "Producto ejemplo"}
# Incluir el router
app.include_router(productos_router)
En este ejemplo, las rutas se accederán como /api/v1/productos
y /api/v1/productos/{producto_id}
. La etiqueta "productos" agrupará estas rutas en la documentación automática de FastAPI.
Ejemplo práctico con templates
Considerando que ya trabajas con templates, aquí tienes un ejemplo de cómo organizar rutas que renderizan templates usando APIRouter:
from fastapi import FastAPI, APIRouter, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
app = FastAPI()
templates = Jinja2Templates(directory="templates")
# Router para páginas web
web_router = APIRouter(
prefix="/web",
tags=["páginas web"]
)
@web_router.get("/dashboard", response_class=HTMLResponse)
async def mostrar_dashboard(request: Request):
datos = {"usuarios_activos": 150, "ventas_hoy": 25}
return templates.TemplateResponse(
"dashboard.html",
{"request": request, "datos": datos}
)
@web_router.get("/perfil", response_class=HTMLResponse)
async def mostrar_perfil(request: Request):
usuario = {"nombre": "Ana García", "email": "ana@ejemplo.com"}
return templates.TemplateResponse(
"perfil.html",
{"request": request, "usuario": usuario}
)
# Incluir el router
app.include_router(web_router)
Las rutas estarán disponibles en /web/dashboard
y /web/perfil
, manteniendo organizadas todas las páginas web bajo un mismo prefijo.
Ventajas del uso de APIRouter
El uso de APIRouter aporta varios beneficios inmediatos:
- Organización: Separa la lógica de diferentes funcionalidades en módulos independientes
- Reutilización: Los routers pueden reutilizarse en diferentes aplicaciones
- Colaboración: Diferentes desarrolladores pueden trabajar en routers separados sin conflictos
- Mantenimiento: Es más fácil localizar y modificar funcionalidades específicas
Un router bien estructurado hace que el código sea más legible y mantenible, especialmente cuando la aplicación crece en complejidad y número de rutas.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Organizar rutas en múltiples archivos
A medida que tu aplicación FastAPI crece, mantener todas las rutas en un solo archivo se vuelve impracticable. La organización en múltiples archivos permite dividir la funcionalidad por dominios o características, creando una estructura de proyecto más profesional y mantenible.
La estrategia más efectiva consiste en crear archivos separados para cada grupo de rutas relacionadas, donde cada archivo contiene su propio APIRouter con funcionalidades específicas.
Estructura de archivos recomendada
Una estructura típica para organizar rutas en múltiples archivos sigue este patrón:
mi_proyecto/
├── main.py
├── routers/
│ ├── __init__.py
│ ├── usuarios.py
│ ├── productos.py
│ └── auth.py
└── templates/
├── usuarios/
└── productos/
Esta estructura separa cada dominio funcional en su propio archivo, facilitando el desarrollo y mantenimiento del código.
Creación de routers en archivos separados
Comenzamos creando el archivo routers/usuarios.py
con todas las rutas relacionadas con usuarios:
# routers/usuarios.py
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
# Configurar templates
templates = Jinja2Templates(directory="templates")
# Crear el router específico para usuarios
router = APIRouter(
prefix="/usuarios",
tags=["usuarios"]
)
@router.get("/", response_class=HTMLResponse)
async def listar_usuarios(request: Request):
usuarios = [
{"id": 1, "nombre": "Ana García", "email": "ana@ejemplo.com"},
{"id": 2, "nombre": "Carlos López", "email": "carlos@ejemplo.com"}
]
return templates.TemplateResponse(
"usuarios/lista.html",
{"request": request, "usuarios": usuarios}
)
@router.get("/{usuario_id}", response_class=HTMLResponse)
async def ver_usuario(request: Request, usuario_id: int):
usuario = {"id": usuario_id, "nombre": "Ana García", "email": "ana@ejemplo.com"}
return templates.TemplateResponse(
"usuarios/detalle.html",
{"request": request, "usuario": usuario}
)
@router.post("/")
async def crear_usuario(nombre: str, email: str):
return {"mensaje": f"Usuario {nombre} creado con email {email}"}
De manera similar, creamos routers/productos.py
para gestionar todo lo relacionado con productos:
# routers/productos.py
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
templates = Jinja2Templates(directory="templates")
router = APIRouter(
prefix="/productos",
tags=["productos"]
)
@router.get("/", response_class=HTMLResponse)
async def listar_productos(request: Request):
productos = [
{"id": 1, "nombre": "Laptop", "precio": 899.99},
{"id": 2, "nombre": "Mouse", "precio": 29.99}
]
return templates.TemplateResponse(
"productos/catalogo.html",
{"request": request, "productos": productos}
)
@router.get("/{producto_id}")
async def obtener_producto(producto_id: int):
return {"id": producto_id, "nombre": "Laptop", "precio": 899.99}
Importación y registro en main.py
El archivo principal main.py
se encarga únicamente de importar y registrar todos los routers:
# main.py
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
# Importar los routers
from routers import usuarios, productos
# Crear la aplicación principal
app = FastAPI(title="Mi Aplicación", version="1.0.0")
# Configurar archivos estáticos
app.mount("/static", StaticFiles(directory="static"), name="static")
# Registrar todos los routers
app.include_router(usuarios.router)
app.include_router(productos.router)
# Ruta principal opcional
@app.get("/")
async def inicio():
return {"mensaje": "Bienvenido a mi aplicación"}
Con esta configuración, las rutas estarán disponibles en:
/usuarios/
- Lista de usuarios/usuarios/{usuario_id}
- Detalle de usuario específico/productos/
- Catálogo de productos/productos/{producto_id}
- Detalle de producto específico
Organización avanzada con subcarpetas
Para aplicaciones más complejas, puedes organizar los routers en subcarpetas temáticas:
routers/
├── __init__.py
├── api/
│ ├── __init__.py
│ ├── usuarios.py
│ └── productos.py
└── web/
├── __init__.py
├── paginas.py
└── formularios.py
En este caso, el archivo routers/api/usuarios.py
contendría las rutas de API, mientras que routers/web/paginas.py
manejaría las páginas web:
# routers/web/paginas.py
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
templates = Jinja2Templates(directory="templates")
router = APIRouter(
prefix="/web",
tags=["páginas web"]
)
@router.get("/inicio", response_class=HTMLResponse)
async def pagina_inicio(request: Request):
return templates.TemplateResponse(
"inicio.html",
{"request": request, "titulo": "Página de Inicio"}
)
Importación desde subcarpetas
Para importar routers desde subcarpetas, actualiza el main.py
:
# main.py
from fastapi import FastAPI
from routers.api import usuarios as api_usuarios
from routers.web import paginas as web_paginas
app = FastAPI()
# Registrar routers con alias para evitar conflictos
app.include_router(api_usuarios.router)
app.include_router(web_paginas.router)
Ventajas de la organización en múltiples archivos
Esta aproximación ofrece beneficios significativos para el desarrollo profesional:
- Separación de responsabilidades: Cada archivo maneja un dominio específico
- Facilita el trabajo en equipo: Diferentes desarrolladores pueden trabajar en archivos separados
- Reduce conflictos: Menos probabilidad de conflictos al fusionar código
- Mejora la legibilidad: Es más fácil encontrar y modificar funcionalidades específicas
- Escalabilidad: La aplicación puede crecer sin que el código se vuelva inmanejable
La modularización es una práctica esencial en el desarrollo de aplicaciones web profesionales, y FastAPI facilita enormemente esta tarea mediante el sistema de APIRouter.
Aprendizajes de esta lección
- Comprender qué es APIRouter y su función en FastAPI.
- Aprender a crear y usar routers básicos para definir rutas.
- Integrar routers en la aplicación principal con prefijos y etiquetas.
- Organizar rutas en múltiples archivos para mejorar la mantenibilidad.
- Implementar estructuras avanzadas con subcarpetas para proyectos complejos.
Completa FastAPI y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs