404 Not Found

404 Not Found


nginx

Parâmetros de Path e Query — Design de Roteamento Preciso

O design de roteamento é como o planejamento urbano—os parâmetros de path são como endereços de ruas (localização precisa), e os parâmetros de query são como critérios de filtro (reduzindo o escopo); somente quando os dois trabalham juntos você encontra rapidamente seu destino.

1. O Que Você Vai Aprender


2. A História Real da Alice

(1) Problema: Parâmetros de Consulta de Produto Confusos na API

O PriceTracker da Alice precisa suportar múltiplos métodos de consulta: consultas exatas por ID do produto, filtragem por categoria e faixa de preço, e navegação paginada por ordem de classificação. Bob enviou category=electronics&min_price=10&max_price=999 do front end, mas o código Flask da Alice analisa cada parâmetro manualmente. Conversões de tipo são propensas a erros, e não há validações para preços negativos ou campos de ordenação inválidos, resultando em incidentes frequentes em produção.

(2) Soluções para Validação de Parâmetros no FastAPI

O FastAPI usa type hints para analisar e validar parâmetros automaticamente. Path() e Query() fornecem restrições declarativas, e parâmetros inválidos acionam automaticamente um erro 422.

PYTHON
from fastapi import FastAPI, Path, Query

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(gt=0, description="Product ID must be positive"),
    category: str | None = Query(None, max_length=50),
):
    return {"product_id": product_id, "category": category}

(3) Resultado

O código de validação de parâmetros foi reduzido de 30 linhas para 3, e as respostas de erro 422 agora incluem automaticamente detalhes específicos sobre a falha de validação, permitindo que Bob identifique imediatamente qual parâmetro está incorreto. A documentação da API também exibe automaticamente todas as restrições.


3. Explicação Detalhada dos Parâmetros de Path

(1) Parâmetros de Path Básicos

Parâmetros de path são parte do caminho da URL e são definidos usando a sintaxe {param}; o FastAPI os converte automaticamente com base nos type hints.

100%
sequenceDiagram
    participant Client
    participant Router as FastAPI Router
    participant Converter as Type Converter
    participant Validator as Path Validator
    participant Handler as View Function

    Client->>Router: GET /products/42
    Router->>Converter: Extract "42" from path
    Converter->>Converter: int("42") → 42
    Converter->>Validator: product_id=42 (int)
    Validator->>Validator: Check gt=0 → 42 > 0 ✓
    Validator->>Handler: get_product(product_id=42)
    Handler-->>Client: {"product_id": 42}
Tipo de Parâmetro de Path Exemplo de URL Tipo Python Conversão Automática
Inteiro /products/42 int "42"42
Ponto flutuante /prices/9.99 float "9.99"9.99
String /categories/electronics str Como está
Path /files/src/main.py Path String contendo /

(1) ▶ Exemplo: Parâmetros de Path Básicos e Conversão de Tipo

PYTHON
from fastapi import FastAPI

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(product_id: int):
    # FastAPI converte automaticamente "42" para int(42)
    # Se o usuário enviar /products/abc → erro 422
    return {"product_id": product_id, "type": str(type(product_id))}

Saída:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Saída (/products/42):

TEXT
{"product_id": 42, "type": "<class 'int'>"}

(2) Validação de Restrições com Path()

Path() adiciona restrições como faixas numéricas e comprimentos de string aos parâmetros de path; estas são refletidas automaticamente na documentação OpenAPI.

Parâmetro de Restrição Tipo Aplicável Significado
gt int/float maior que (>)
ge int/float maior ou igual a (>=)
lt int/float menor que (<)
le int/float menor ou igual a (<=)
min_length str Comprimento Mínimo
max_length str Comprimento Máximo
pattern str Correspondência de expressão regular
description Todos Descrição OpenAPI

(2) ▶ Exemplo: Restrições Numéricas com Path()

PYTHON
from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(
        gt=0,
        le=1000000,
        description="Product ID: inteiro positivo, máx 1 milhão",
    ),
):
    return {"product_id": product_id}

Saída:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Saída (/products/-1 retorna 422):

TEXT
{
  "detail": [
    {
      "loc": ["path", "product_id"],
      "msg": "Input should be greater than 0",
      "type": "greater_than"
    }
  ]
}

4. Explicação Detalhada dos Parâmetros de Query

(1) Parâmetros de Query Básicos

Parâmetros de query são os pares chave-valor que seguem ? na URL. Eles são declarados como parâmetros de função, e parâmetros com valores padrão são opcionais.

Tipo de Parâmetro de Query Método de Declaração Obrigatório
Obrigatório category: str Sim
Opcional (padrão) category: str = "all" Não
Opcional (None) `category: str None = None`

(1) ▶ Exemplo: Noções Básicas de Parâmetros de Query

PYTHON
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/prices")
async def search_prices(
    category: str | None = Query(None, max_length=50, description="Categoria do produto"),
    min_price: float = Query(0.0, ge=0, description="Preço mínimo em USD"),
    max_price: float = Query(999999.0, le=999999, description="Preço máximo em USD"),
):
    return {
        "category": category,
        "price_range": f"${min_price} - ${max_price}",
    }

Saída:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Saída (/prices?category=electronics&min_price=10&max_price=500):

TEXT
{"category": "electronics", "price_range": "$10.0 - $500.0"}

(2) Opções Avançadas do Query()

Opção Função Exemplo
alias Aliases de parâmetro (ex.: camelCase para snake_case) Query(alias="minPrice")
deprecated Marcar como Obsoleto Query(deprecated=True)
title Título OpenAPI Query(title="Category Filter")
description Descrição OpenAPI Query(description="...")
examples Valor de Exemplo Query(examples=["electronics"])

(2) ▶ Exemplo: alias e deprecated

PYTHON
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/products")
async def list_products(
    sort_by: str = Query(
        "name",
        alias="sortBy",
        description="Campo de ordenação: name, price, created_at",
    ),
    old_filter: str | None = Query(
        None,
        deprecated=True,
        description="Use sort_by em vez disso",
    ),
):
    return {"sort_by": sort_by}

Saída:

TEXT
# Função definida com sucesso

5. Parâmetros de Enumeração

(1) Limitando os Valores Possíveis em uma Enumeração de String

Quando um parâmetro só pode assumir um conjunto fixo de valores, use a restrição Enum, e o FastAPI exibirá automaticamente um menu suspenso na documentação.

(1) ▶ Exemplo: Enumerando Parâmetros de Path

PYTHON
from enum import Enum
from fastapi import FastAPI

class Category(str, Enum):
    electronics = "electronics"
    clothing = "clothing"
    food = "food"
    books = "books"

app = FastAPI()

@app.get("/categories/{category}")
async def get_category(category: Category):
    return {
        "category": category,
        "value": category.value,
        "label": category.name,
    }

Saída:

TEXT
INFO:     127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK

Saída (/categories/electronics):

TEXT
{"category": "electronics", "value": "electronics", "label": "electronics"}

(2) ▶ Exemplo: Enumerando Parâmetros de Query e Ordenação

PYTHON
from enum import Enum
from fastapi import FastAPI, Query

class SortOrder(str, Enum):
    asc = "asc"
    desc = "desc"

app = FastAPI()

@app.get("/products")
async def list_products(
    sort_order: SortOrder = Query(SortOrder.asc),
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "sort": sort_order.value,
        "limit": limit,
        "offset": offset,
    }

Saída:

TEXT
# Função definida com sucesso

6. Combinando Múltiplos Parâmetros e Armadilhas

(1) Regras para a Ordem de Declaração de Parâmetros

Regras do FastAPI para determinar os tipos de parâmetros: Qualquer {param} no path é um parâmetro de path; caso contrário, é um parâmetro de query (parâmetros com anotações de tipo são obrigatórios, e aqueles com valores padrão são opcionais).

Ordem Tipo de Parâmetro Critério
1 Parâmetro de Path URL contém {param}
2 Parâmetros de query (obrigatórios) Sem valor padrão; não incluído no path
3 Parâmetros de query (opcionais) Possui valor padrão ou None

(1) ▶ Exemplo: Combinando Múltiplos Parâmetros—Busca de Produtos do PriceTracker

PYTHON
from fastapi import FastAPI, Path, Query
from enum import Enum

class Category(str, Enum):
    electronics = "electronics"
    clothing = "clothing"
    food = "food"

app = FastAPI()

@app.get("/products/{product_id}/prices")
async def get_product_prices(
    product_id: int = Path(gt=0, description="Product ID"),
    category: Category | None = Query(None, description="Filtrar por categoria"),
    min_price: float = Query(0.0, ge=0, description="Preço mín em USD"),
    max_price: float = Query(99999.0, ge=0, description="Preço máx em USD"),
    sort: str = Query("date", pattern="^(date|price)$"),
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "product_id": product_id,
        "category": category,
        "price_range": [min_price, max_price],
        "sort": sort,
        "pagination": {"limit": limit, "offset": offset},
    }

Saída:

TEXT
# Função definida com sucesso

(2) Armadilhas Comuns

Armadilhas Sintaxe Incorreta Sintaxe Correta
Parâmetro de path é opcional product_id: int = None Parâmetro de path é obrigatório
Valor padrão conflita com Query limit: int = 20, Query(ge=1) limit: int = Query(20, ge=1)
Parâmetros opcionais: None category: str = None `category: str
Enumerações Não Usam a Classe Base str class Cat(Enum): class Cat(str, Enum):

7. Exemplo Completo

Parâmetros de path, parâmetros de query e restrições de enumeração são a base para construir APIs flexíveis. Abaixo, combinamos restrições de path, paginação de query e filtragem de enumeração.

PYTHON
from fastapi import FastAPI, Path, Query
from enum import Enum

app = FastAPI()

class SortOrder(str, Enum):
    asc = "asc"
    desc = "desc"

PRODUCTS = [{"id": i, "name": f"Product-{i}", "price": i * 10.0} for i in range(1, 101)]

@app.get("/products/{product_id}")
async def get_product(
    product_id: int = Path(gt=0, description="Product ID"),
    sort: SortOrder = Query(SortOrder.asc),
    limit: int = Query(10, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    return {
        "product_id": product_id,
        "sort": sort.value,
        "limit": limit,
        "offset": offset,
    }

Saída:

TEXT
GET /products/5?sort=desc&limit=20&offset=10 → {"product_id":5,"sort":"desc","limit":20,"offset":10}
GET /products/0 → 422 Validation Error (product_id must be > 0)

❓ Perguntas Frequentes

P Parâmetros de path e query podem ter o mesmo nome?
R Não. O FastAPI lançará um erro porque não pode distinguir entre parâmetros com o mesmo nome.
P Como faço para tornar um parâmetro de query obrigatório?
R Simplesmente não forneça um valor padrão. Por exemplo, category: str é obrigatório, enquanto category: str = "all" é opcional. Você também pode marcar explicitamente um parâmetro como obrigatório usando Query(...).
P Mensagens de erro muito detalhadas (como o erro 422) poderiam expor informações sensíveis?
R Mensagens de erro detalhadas são úteis durante o desenvolvimento. Em um ambiente de produção, você pode usar um manipulador de exceção personalizado para simplificar a resposta e retornar apenas "Falha na validação do parâmetro."
P Parâmetros Enum podem aceitar letras minúsculas?
R Por padrão, eles diferenciam maiúsculas de minúsculas. Se você quiser que sejam insensíveis a maiúsculas, precisa definir um validador personalizado ou usar letras minúsculas nos valores do Enum.
P Qual é a diferença entre "gt" e "ge" em Path()?
R gt=0 significa que o valor deve ser > 0 (excluindo 0), enquanto ge=0 significa >= 0 (incluindo 0). Parâmetros do tipo ID geralmente usam gt=0, enquanto parâmetros do tipo preço usam ge=0.
P Como limito o comprimento dos parâmetros de query?
R Use Query(max_length=N) para limitar o comprimento de strings, e Query(ge=N, le=M) para limitar faixas numéricas.

📖 Resumo


📝 Exercícios

  1. Problema Básico (Dificuldade ⭐): Crie um endpoint GET /items/{item_id} que receba item_id (um inteiro positivo) como entrada e retorne {"item_id": item_id}. Dica: item_id: int = Path(gt=0)
  2. Problema Avançado (Dificuldade ⭐⭐): Crie o endpoint de consulta /products para o PriceTracker, que suporta três parâmetros de query: category (string opcional, até 50 caracteres), min_price (≥0), e max_price (≤999999). Dica: Query(None, max_length=50)
  3. Desafio (Dificuldade: ⭐⭐⭐): Crie um endpoint /products/{product_id}/prices e, usando parâmetros de path (product_id > 0), parâmetros de query de enumeração (SortOrder: asc/desc), e parâmetros de paginação (limit 1-100, offset ≥ 0), verifique que entradas inválidas retornam um erro 422. Dica: Defina SortOrder(str, Enum) e múltiplos endpoints Query().

---|

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%