(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo versionar una API de Datos con FastAPI y OpenAPI

João Barros 20 de July de 2026 4 min de lectura

Este tutorial muestra cómo versionar una API de Datos con FastAPI y OpenAPI de forma práctica y útil. Saber versionar una API permite introducir cambios sin romper clientes, documentar diferencias y gestionar migraciones con menos riesgo.

Requisitos previos

  • Python 3.9+ y pip instalados
  • Conocimientos básicos de FastAPI y HTTP
  • Editor de código y terminal

Paso 1: preparar el entorno

Crea un entorno virtual e instala FastAPI y Uvicorn. Usamos dependencias mínimas para centrarnos en el versionado.

python -m venv .venv
source .venv/bin/activate  # ou .venv\Scripts\activate no Windows
pip install fastapi uvicorn

Paso 2: crear routers separados por versión (path versioning)

Un enfoque simple y explícito es usar prefijos como /v1 y /v2. Cada router tiene su implementación, permitiendo cambios internos sin impacto entre versiones.

# app/main.py
from fastapi import FastAPI
from .routers import v1, v2

app = FastAPI(title="API de Dados - Exemplo")
app.include_router(v1.router, prefix="/v1", tags=["v1"])
app.include_router(v2.router, prefix="/v2", tags=["v2"]) 

# routers/v1.py
from fastapi import APIRouter

router = APIRouter()

@router.get("/items")
def list_items():
    # resposta simples v1
    return {"version": "v1", "items": ["a", "b"]}

# routers/v2.py
from fastapi import APIRouter

router = APIRouter()

@router.get("/items")
def list_items():
    # resposta diferente em v2 (exemplo: items com id)
    return {"version": "v2", "items": [{"id":1, "name":"a"}, {"id":2, "name":"b"}]}

Paso 3: negociación de versión vía header (header versioning)

Algunos equipos prefieren negociar la versión con una cabecera para mantener URLs estables. Aquí mostramos un middleware sencillo que reroutea al router adecuado usando una cabecera personalizada Accept-Version.

# app/version_middleware.py
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import Request
from fastapi.responses import JSONResponse

class VersionRoutingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        version = request.headers.get("Accept-Version")
        # si existe la cabecera, prefixa la path con /v{n}
        if version and not request.url.path.startswith(f"/v{version}"):
            # reescribe el scope para simular una petición a /v{version}/... 
            new_path = f"/v{version}{request.url.path}"
            request.scope["path"] = new_path
            request.scope["raw_path"] = new_path.encode()
        return await call_next(request)

# registrar en main.py
from .version_middleware import VersionRoutingMiddleware
app.add_middleware(VersionRoutingMiddleware)

Paso 4: documentar diferencias con OpenAPI y metadata

FastAPI genera OpenAPI automáticamente. Usa description, tags y operationId para clarificar diferencias entre versiones y añade deprecated cuando sea necesario.

# ejemplo de endpoint con deprecación
@router.get("/items", deprecated=True, summary="Listar items (v1 - obsoleto)")
def list_items():
    return {"version": "v1", "items": []}

# en FastAPI, la documentación está en /docs (Swagger UI) y /redoc

Paso 5: estrategias para compatibilidad y migración

Define reglas internas: ¿qué es un breaking change? Cambios en el contrato (campos, tipos) son breaking. Para minimizar impacto:

  • Prefiere añadir campos en lugar de eliminar
  • Marca endpoints obsoletos con deprecated y mantenlos durante un periodo
  • Documenta claramente en el OpenAPI y en los changelogs las diferencias
  • Si es necesario, ofrece una cabecera informativa (ej.: X-Deprecation-Date) para avisar a los clientes

Verificar el resultado

Inicia la aplicación con Uvicorn y prueba los dos tipos de versioning.

uvicorn app.main:app --reload

# path versioning
curl http://127.0.0.1:8000/v1/items
curl http://127.0.0.1:8000/v2/items

# header versioning (aplicando middleware)
curl -H "Accept-Version: 2" http://127.0.0.1:8000/items

# abrir documentación
# https://127.0.0.1:8000/docs  (Swagger UI)

Verifica que el output difiere según la versión y que /docs muestra tags separadas para v1 y v2. Prueba la deprecación observando el campo deprecated en los endpoints.

Conclusión

Versionar una API de Datos con FastAPI y OpenAPI permite gestionar cambios de forma controlada: usa path versioning para claridad y header versioning para URLs estables, documenta en OpenAPI y marca endpoints obsoletos. Paso siguiente: añadir tests automatizados que validen la compatibilidad entre versiones (contract tests). Consejo: empieza por definir una política de versionado (semver o sólo major) antes de publicar la primera versión.