Parâmetros de Rota em FastAPI
Os parâmetros de rota permitem que valores específicos sejam passados diretamente no caminho da URL. No FastAPI, esses valores são vinculados automaticamente aos argumentos da função que processa a requisição. Esses parâmetros, também conhecidos como path parameters, são úteis para configurar endpoints dinâmicos e transferir informações diretamente pela URL.
Definição de Parâmetros de Rota
Parâmetros de rota são declarados diretamente na rota, delimitados por chaves {}
. Veja o exemplo abaixo:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{id}")
def get_user(id: int):
return {"user_id": id}
Nesse caso, o decorador app.get
utiliza a rota "/users/{id}"
. O {id}
define o parâmetro de rota id
.
A função get_user()
, que processa as requisições enviadas para essa rota, recebe o parâmetro id
. O valor correspondente ao segmento da URL será passado automaticamente para a função, conforme interpretado pelo FastAPI.
Considere uma requisição para o endereço http://127.0.0.1:8000/users/315
. O caminho da URL é users/315
. O FastAPI reconhece que esse caminho corresponde à rota "/users/{id}"
e, portanto, a função get_user()
será chamada.
O parâmetro id
na rota corresponde ao segundo segmento do caminho. Assim, o framework associa o valor "315"
ao parâmetro id
. Ao acessar a URL http://127.0.0.1:8000/users/315
, a função get_user()
receberá id=315
.
O FastAPI também suporta a definição de múltiplos parâmetros de rota. Veja o exemplo abaixo:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{name}/{age}")
def get_user(name, age):
return {"user_name": name, "user_age": age}
Nesse caso, a função get_user()
processará requisições que correspondam à rota "/users/{name}/{age}"
. Essa rota espera um caminho com três segmentos: o primeiro é users
, o segundo representa o parâmetro name
, e o terceiro, o parâmetro age
.
Por exemplo, uma requisição para http://127.0.0.1:8000/users/Tom/38
resultará em:
{
"user_name": "Tom",
"user_age": "38"
}
Embora o separador padrão entre os segmentos de uma rota seja a barra (/
), é possível utilizar outros caracteres, como o hífen (-
). Veja o exemplo:
@app.get("/users/{name}-{age}")
def get_user(name, age):
return {"user_name": name, "user_age": age}
Nesse caso, uma requisição para http://127.0.0.1:8000/users/Joao-25
será interpretada corretamente pelo FastAPI. O framework identificará os valores do parâmetro name
como "Joao"
e do parâmetro age
como "25"
.
Ordem de Definição das Rotas
Ao definir rotas, é importante considerar que podem surgir ambiguidades entre elas, quando uma requisição corresponde a mais de uma rota definida. Por isso, a ordem em que as rotas são declaradas no código deve ser cuidadosamente planejada. Veja o exemplo abaixo:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{name}")
def get_user(name):
return {"user_name": name}
@app.get("/users/admin")
def get_admin():
return {"message": "Hello admin"}
Nesse caso, queremos que as requisições para a rota "/users/admin"
sejam processadas pela função get_admin()
. Já as requisições que seguem o padrão "/users/{name}"
, onde o segundo segmento representa o parâmetro name, devem ser processadas pela função get_user()
.
No entanto, ao acessar o endereço http://127.0.0.1:8000/users/admin
, vemos que a requisição é tratada pela função get_user()
, e não pela get_admin()
.
Isso ocorre porque a função get_user
foi definida antes da função get_admin
. Portanto, a rota "/users/{name}"
é avaliada primeiro, e qualquer requisição que corresponda a esse padrão será tratada por ela.
Para resolver esse problema, basta trocar a ordem das definições das funções:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/admin")
def get_admin():
return {"message": "Hello admin"}
@app.get("/users/{name}")
def get_user(name):
return {"user_name": name}
Restrições de Tipo para Parâmetros
O FastAPI permite definir restrições de tipo para os parâmetros de rota. Isso é feito especificando o tipo esperado diretamente na declaração do parâmetro. Por exemplo, podemos configurar o parâmetro id para aceitar apenas números inteiros:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{id: int}")
def get_user(id: int):
return {"user_id": id}
Ao declarar explicitamente o tipo int
para o parâmetro id
, garantimos que ele só aceitará valores inteiros. Se uma requisição enviar um valor não numérico para esse parâmetro, o servidor retornará automaticamente uma mensagem de erro indicando o problema.
Além de int, o FastAPI permite especificar outros tipos de daddos, como str
, float
, bool
, entre outros.
Validação de Parâmetros com a classe Path
O FastAPI fornece a classe Path
do módulo fastapi
para facilitar a validação de parâmetros de rota. Com a classe Path
, é possível aplicar diversas validações aos valores recebidos. Entre os parâmetros disponíveis no construtor de Path
, destacam-se:
min_length
: define o número mínimo de caracteres que o valor deve ter.max_length
: define o número máximo de caracteres que o valor pode ter.pattern
: aplica uma expressão regular ao valor, que deve ser correspondida.lt
: o valor deve ser menor que o especificado.le
: o valor deve ser menor ou igual ao especificado.gt
: o valor deve ser maior que o especificado.ge
: o valor deve ser maior ou igual ao especificado.
Veja um exemplo de uso da classe Path
para validar o número de caracteres de um parâmetro de rota:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{name}")
def get_user(name: str = Path(min_length=3, max_length=20)):
return {"name": name}
Neste exemplo, o parâmetro name
é recebido na rota. O valor desse parâmetro deve ter pelo menos 3 caracteres e no máximo 20 caracteres.
Da mesma forma, podemos aplicar validações numéricas a parâmetros inteiros. Por exemplo, podemos definir que o parâmetro age
deve ser maior ou igual a 18 e menor que 111:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{name}/{age}")
def get_user(
name: str = Path(min_length=3, max_length=20),
age: int = Path(ge=18, lt=111)
):
return {"name": name, "age": age}
Além disso, podemos aplicar expressões regulares para validar o formato de um parâmetro. Por exemplo, podemos definir que o parâmetro phone
deve conter exatamente 11 dígitos:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{phone}")
def get_phone(phone: str = Path(pattern=r"^\d{11}$")):
return {"phone": phone}
Documentação oficial: