404 Not Found

404 Not Found


nginx

Documentação de API e Personalização OpenAPI — Criando Documentação de API Profissional

A documentação de API é como um manual de produto — sem ela, os clientes (desenvolvedores) não usarão seu produto; se for mal escrita, os clientes votarão com os pés. A geração automática de documentação é a arma secreta do FastAPI, mas a configuração padrão é apenas o ponto de partida; a personalização é o que diferencia os profissionais.

1. O Que Você Vai Aprender


2. A História Real da Alice

(1) Problema: A documentação padrão não é profissional o suficiente

A documentação da API do PriceTracker da Alice usa o Swagger UI padrão do FastAPI, onde todos os endpoints estão misturados sem agrupamento, então Bob não consegue encontrar o endpoint que precisa. Para piorar, a documentação não possui exemplos de requisição, então Bob não sabe qual valor inserir no campo currency; não há versionamento para corpos de requisição ou resposta; e endpoints novos e obsoletos estão todos misturados.

(2) Soluções Personalizadas para OpenAPI

O FastAPI permite personalização profunda da documentação OpenAPI — incluindo agrupamento por tags, valores de exemplo, marcadores de obsolescência e schemas personalizados — transformando a documentação da API de apenas "legível" para "utilizável."

(3) Resultado

Bob pode simplesmente abrir a documentação para localizar rapidamente endpoints por tag (Products/Prices/Auth). Valores de exemplo eliminam a necessidade de adivinhar ao fazer requisições, e endpoints obsoletos são marcados em cinza para evitar uso acidental. Como resultado, a qualidade da documentação foi elevada do nível de "referência interna" para "lançamento público."


3. Configuração do Swagger UI e ReDoc

(1) Processo de Geração OpenAPI

100%
flowchart LR
    A[FastAPI Routes] --> B[Pydantic Models]
    B --> C[OpenAPI 3.1 Schema]
    C --> D[Swagger UI /docs]
    C --> E[ReDoc /redoc]
    C --> F[Raw JSON /openapi.json]

(1) ▶Exemplo: Configuração de Documentação em Nível de Aplicação FastAPI

PYTHON
from fastapi import FastAPI

app = FastAPI(
    title="PriceTracker API",
    description="""
    ## PriceTracker SaaS API
    
    Serviço de rastreamento de preços de e-commerce para monitoramento de preços em nível de milhões de produtos.
    
    ### (1) Autenticação
    Todos os endpoints protegidos exigem um token Bearer obtido em `/auth/login`.
    
    ### (2) Limites de Taxa
    - Free: 100 requisições/min
    - Pro: 1000 requisições/min
    - Enterprise: ilimitado
    """,
    version="1.0.0",
    terms_of_service="https://pricetracker.example.com/terms",
    contact={
        "name": "PriceTracker Support",
        "url": "https://pricetracker.example.com/support",
        "email": "support@pricetracker.example.com",
    },
    license_info={
        "name": "MIT License",
        "url": "https://opensource.org/licenses/MIT",
    },
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
)

Saída:

TEXT
# Execução Bem-sucedida

(3) ▶Exemplo: Personalizando Parâmetros do Swagger UI

PYTHON
app = FastAPI(
    swagger_ui_parameters={
        "persistAuthorization": True,  # Manter autenticação entre refreshes de página
        "displayRequestDuration": True,  # Mostrar duração da requisição
        "filter": True,  # Habilitar filtro de busca
        "syntaxHighlight.theme": "monokai",  # Tema de destaque de código
        "defaultModelsExpandDepth": 1,  # Expandir modelos 1 nível de profundidade
        "defaultModelExpandDepth": 1,
    }
)

Saída:

TEXT
# Execução Bem-sucedida
Parâmetro Padrão Descrição
persistAuthorization False Manter autenticação ao atualizar a página
displayRequestDuration False Mostrar duração da requisição
filter False Habilitar Filtro de Busca
defaultModelsExpandDepth 1 Profundidade de Expansão do Modelo
syntaxHighlight.theme "agate" Tema de Destaque de Código

4. Agrupamento por Tags e Marcadores de Obsolescência

(1) Tags: Endpoints Agrupados

(1) ▶Exemplo: Definindo Tags

PYTHON
from fastapi import FastAPI, APIRouter

tags_metadata = [
    {
        "name": "auth",
        "description": "Operações de autenticação. Login, registro, renovação de token.",
    },
    {
        "name": "products",
        "description": "Gerenciamento de produtos. Operações CRUD para produtos rastreados.",
    },
    {
        "name": "prices",
        "description": "Dados de preço. Consultar, importar e rastrear mudanças de preço.",
    },
    {
        "name": "admin",
        "description": "Operações administrativas. Requer papel de admin.",
    },
]

app = FastAPI(
    title="PriceTracker API",
    openapi_tags=tags_metadata,
)

Saída:

TEXT
# Execução Bem-sucedida

(2) ▶Exemplo: Atribuição de Tags a Endpoints

PYTHON
@app.post("/auth/login", tags=["auth"])
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    ...

@app.get("/api/v1/products", tags=["products"])
async def list_products():
    ...

@app.post("/api/v1/prices", tags=["prices"])
async def create_price():
    ...

@app.get("/api/v1/admin/stats", tags=["admin"])
async def admin_stats():
    ...

Saída:

TEXT
# Função definida com sucesso

(3) ▶Exemplo: Marcando um endpoint como obsoleto

PYTHON
@app.get(
    "/api/v1/products/{product_id}/history",
    tags=["prices"],
    deprecated=True,
    summary="[DEPRECATED] Use GET /prices?product_id={id} em vez disso",
)
async def get_price_history_deprecated(product_id: int):
    """Este endpoint está obsoleto. Use o endpoint prices com filtro product_id."""
    ...

Saída:

TEXT
# Função definida com sucesso

5. Valores de Exemplo e Templates de Resposta

(1) json_schema_extra e examples

(1) ▶Exemplo: Valores de exemplo para modelos Pydantic

PYTHON
from pydantic import BaseModel, Field

class ProductCreate(BaseModel):
    name: str = Field(
        min_length=1, max_length=200,
        description="Nome de exibição do produto",
        examples=["Mouse Sem Fio", "Hub USB-C", "Teclado Mecânico"],
    )
    category: str = Field(
        max_length=100,
        description="Categoria do produto",
        examples=["eletrônicos", "roupas", "alimentos"],
    )
    base_price: float = Field(
        gt=0,
        description="Preço base em USD",
        examples=[9.99, 49.99, 199.99],
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "name": "Mouse Sem Fio",
                    "category": "eletrônicos",
                    "base_price": 29.99,
                }
            ]
        }
    }

Saída:

TEXT
# Execução Bem-sucedida

(2) ▶Exemplo: Exemplo de resposta em nível de endpoint

PYTHON
from fastapi import FastAPI
from fastapi.responses import JSONResponse

@app.post(
    "/api/v1/products",
    response_model=ProductResponse,
    status_code=201,
    summary="Criar um novo produto",
    description="Criar um novo produto no banco de dados do PriceTracker.",
    responses={
        201: {
            "description": "Produto criado com sucesso",
            "content": {
                "application/json": {
                    "example": {
                        "id": 1,
                        "name": "Mouse Sem Fio",
                        "category": "eletrônicos",
                        "base_price": 29.99,
                    }
                }
            },
        },
        401: {"description": "Autenticação necessária"},
        403: {"description": "Permissões insuficientes"},
        422: {"description": "Erro de validação"},
    },
)
async def create_product(product: ProductCreate):
    ...

Saída:

TEXT
# Função definida com sucesso

6. Schema OpenAPI Personalizado

(1) generate_unique_id_function

(1) ▶Exemplo: Gerando um ID de Endpoint Personalizado

PYTHON
from fastapi import FastAPI

def custom_generate_unique_id(route):
    # Formato: {method}_{tag}_{path}
    tags = route.tags or ["default"]
    tag = tags[0]
    method = route.methods.pop() if route.methods else "GET"
    path = route.path.replace("/", "_").strip("_").replace("{", "").replace("}", "")
    return f"{method}_{tag}_{path}"

app = FastAPI(
    generate_unique_id_function=custom_generate_unique_id,
)

Saída:

TEXT
# Função definida com sucesso

(2) Comparação de Melhores Práticas de Documentação

Dimensão Padrão Melhor Prática
Grupos de Endpoints Nenhum Tags por Função
Endpoints abandonados Misturados com endpoints normais deprecated=True marca cinza
Exemplo de Requisição Nenhum examples + json_schema_extra
Templates de Resposta Apenas 200 Cobertura Completa para 201/401/403/422
Descrição Nome de Função Simples Summary + Description
Informação de Certificação Nenhuma Página Inicial da Documentação: Explicação de Métodos de Certificação
Versionamento Versão Única Versionamento por Path de URL /api/v1/

❓Perguntas Frequentes

P Qual é a diferença entre Swagger UI e ReDoc?
R O Swagger UI é interativo (permite testar APIs), enquanto o ReDoc é projetado para leitura (mais atraente visualmente). Recomendamos ReDoc para documentação externa e Swagger UI para desenvolvimento interno.
P Como posso ocultar certos endpoints para que não apareçam na documentação?
R Defina include_in_schema=False: @app.get("/internal", include_in_schema=False). Isso é adequado para health checks internos e endpoints de monitoramento.
P Devo usar OpenAPI versão 3.0 ou 3.1?
R O FastAPI gera OpenAPI 3.1 por padrão (que suporta os recursos mais recentes do JSON Schema). Se precisar de compatibilidade com ferramentas mais antigas, você pode fazer downgrade da versão na função openapi personalizada.
P Como adiciono CSS/JS personalizado à documentação?
R Use swagger_ui_parameters para fornecer uma URL de CSS, ou use get_swagger_ui_html para personalizar completamente o HTML.
P Qual é a diferença entre valores de exemplo e valores padrão?
R "examples" são para fins de documentação e não afetam a validação; "default" são os valores padrão reais que afetam o comportamento. Ambos devem ser definidos.
P Como organizar a documentação para múltiplas versões de API?
R Use um APIRouter(prefix="/api/v1") separado para cada versão e distinga as versões usando tags. Alternativamente, crie um sub-aplicativo FastAPI separado para cada versão.

📖Resumo


📝Exercícios

  1. Questão Básica (Dificuldade ⭐): Configure a documentação em nível de aplicação FastAPI para o PriceTracker — incluindo título, descrição, número de versão e informações de contato — e adicione persistAuthorization=True para garantir que o Swagger UI retenha o status de autenticação. Dica: FastAPI(title=..., swagger_ui_parameters={...})
  2. Exercício Avançado (Dificuldade ⭐⭐): Defina 4 tags (auth/products/prices/admin), atribua a tag correta a cada endpoint, marque o endpoint obsoleto com deprecated=True, e verifique se os endpoints estão agrupados por tag no Swagger UI. Dica: openapi_tags=[...] + tags=["products"]
  3. Desafio (Dificuldade ⭐⭐⭐): Adicione um exemplo completo de json_schema_extra ao ProductCreate, e adicione templates de resposta para os códigos de status 201, 401, 403 e 422 (incluindo conteúdo de exemplo) ao endpoint POST /products para implementar a generate_unique_id_function personalizada. Dica: responses={201: {"content": {...}}} + generate_unique_id_function

---|

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%