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
- Parâmetros de path: conversão automática de tipo, validação e restrições
Path()(gt/ge/lt/le) - Parâmetros de Query: Opcional/Obrigatório, Valor Padrão, Validação Avançada
Query()(alias/description/deprecated) - Regras para a Ordem de Combinações de Múltiplos Parâmetros e Armadilhas Comuns
- Parâmetro de Enumeração de String:
Enum—Aplicações em Paths e Queries - Cenário da Alice no PriceTracker: Buscar preços por ID do produto; filtrar por categoria e faixa de preço
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.
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.
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
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:
INFO: 127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK
Saída (
/products/42):
{"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()
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:
INFO: 127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK
Saída (
/products/-1retorna 422):
{
"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
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:
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):
{"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
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:
# 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
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:
INFO: 127.0.0.1:50123 - "GET /api/items HTTP/1.1" 200 OK
Saída (
/categories/electronics):
{"category": "electronics", "value": "electronics", "label": "electronics"}
(2) ▶ Exemplo: Enumerando Parâmetros de Query e Ordenação
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:
# 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
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:
# 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.
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:
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
category: str é obrigatório, enquanto category: str = "all" é opcional. Você também pode marcar explicitamente um parâmetro como obrigatório usando Query(...).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.Query(max_length=N) para limitar o comprimento de strings, e Query(ge=N, le=M) para limitar faixas numéricas.📖 Resumo
- Parâmetros de path são declarados na URL usando
{param}; o FastAPI os converte e valida automaticamente com base nos type hints. Path()adiciona restrições de faixa numérica (gt/ge/lt/le) e restrições de string (min_length/max_length)- Parâmetros de query são declarados como parâmetros de função; aqueles com valores padrão são opcionais, enquanto aqueles sem valores padrão são obrigatórios.
Query()suporta opções avançadas comoalias/deprecated/description/examples, etc.- Parâmetros de enumeração (
str, Enum) restringem os valores disponíveis e exibem automaticamente um menu suspenso na documentação
📝 Exercícios
- Problema Básico (Dificuldade ⭐): Crie um endpoint GET
/items/{item_id}que recebaitem_id(um inteiro positivo) como entrada e retorne{"item_id": item_id}. Dica:item_id: int = Path(gt=0) - Problema Avançado (Dificuldade ⭐⭐): Crie o endpoint de consulta
/productspara o PriceTracker, que suporta três parâmetros de query:category(string opcional, até 50 caracteres),min_price(≥0), emax_price(≤999999). Dica:Query(None, max_length=50) - Desafio (Dificuldade: ⭐⭐⭐): Crie um endpoint
/products/{product_id}/pricese, 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: DefinaSortOrder(str, Enum)e múltiplos endpointsQuery().
---|



