Capítulo 3, Básico
Rotas e requisições GET
Uma rota liga um caminho e um verbo a uma função. Quando a requisição chega, a função roda, e o que ela devolver vira a resposta em JSON.
Várias rotas
Cada decorador (@app.get, @app.post...) registra uma rota. O caminho é a parte da URL depois do endereço do servidor:
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/")
def home():
return {"mensagem": "Bem-vindo ao FastAPI"}
@app.get("/sobre")
def sobre():
return {"mensagem": "Esta é a página sobre"}
@app.get("/usuarios")
def usuarios():
return {"usuarios": ["Mohit", "Rohit", "Amit"]}
cliente = TestClient(app)
for caminho in ("/", "/sobre", "/usuarios"):
resposta = cliente.get(caminho)
print(caminho, resposta.status_code, resposta.json())
/ 200 {'mensagem': 'Bem-vindo ao FastAPI'}
/sobre 200 {'mensagem': 'Esta é a página sobre'}
/usuarios 200 {'usuarios': ['Mohit', 'Rohit', 'Amit']}
O GET só lê: ele não deve alterar nada no servidor. Por isso o navegador pode repetir uma requisição GET sem perigo, e por isso ela pode ser guardada em cache.
O que o navegador mostra
Ao abrir /usuarios no navegador, você vê o JSON bruto, e não uma página bonita. Uma API devolve dados, e quem desenha a tela é o frontend. O cabeçalho da resposta diz isso:
resposta = cliente.get("/usuarios")
print(resposta.headers["content-type"])
application/json
Rota inexistente e verbo errado
Chamar um caminho que não existe devolve 404. Chamar um caminho que existe com o verbo errado devolve 405:
print(cliente.get("/nao-existe").status_code)
resposta = cliente.post("/sobre")
print(resposta.status_code, resposta.json())
404
405 {'detail': 'Method Not Allowed'}
O que o FastAPI registrou
Além das suas três rotas, o FastAPI adicionou as páginas de documentação. Dá para listar tudo o que está registrado:
print([rota.path for rota in app.routes])
['/openapi.json', '/docs', '/docs/oauth2-redirect', '/redoc', '/', '/sobre', '/usuarios']
Documentando as rotas
Os parâmetros do decorador e a docstring da função viram texto na documentação. tags agrupa as rotas, summary dá um título curto e a docstring dá a descrição longa:
@app.get("/produtos", tags=["Produtos"], summary="Lista os produtos")
def produtos():
"""Devolve todos os produtos disponíveis no catálogo."""
return []
operacao = app.openapi()["paths"]["/produtos"]["get"]
print(operacao["tags"], operacao["summary"])
print(operacao["description"])
['Produtos'] Lista os produtos
Devolve todos os produtos disponíveis no catálogo.
Testando no Swagger
Em /docs, clique na rota, depois em Try it out e em Execute. A página mostra o endereço chamado, o corpo da resposta e o código de status. Rotas GET também podem ser testadas direto no navegador. As rotas POST, PUT e DELETE não podem: o navegador só envia GET quando você digita um endereço, e para os outros verbos você usa o Swagger, o curl ou uma ferramenta como o Postman.
Por que JSON?
O objetivo de uma API é trocar dados entre programas. O JSON é leve, legível e entendido por praticamente toda linguagem, e por isso é o formato padrão do FastAPI. O que a sua função devolve (dicionários, listas, modelos do Pydantic) é convertido para JSON automaticamente.
Exercício 1
Uma rota de produtos
Acrescente GET /categorias, que devolva a lista ["livros", "jogos", "música"], e confira o status e o conteúdo.