Chapter 3, Basic
Routes and GET requests
A route links a path and a verb to a function. When the request arrives, the function runs, and what it returns becomes the JSON response.
Multiple routes
Each decorator (@app.get, @app.post...) registers a route. The path is the part of the URL after the server address:
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']}
The GET only reads: it should not change anything on the server. That’s why the browser can repeat a request GET without danger, and that’s why it can be cached.
What the browser shows
When you open /usuarios in the browser, you see the raw JSON, and not a pretty page. An API returns data, and the frontend designs the screen. The response header indicates this:
resposta = cliente.get("/usuarios")
print(resposta.headers["content-type"])
application/json
Non-existent route and wrong verb
Calling a path that does not exist returns 404. Calling a path that exists with the wrong verb returns 405:
print(cliente.get("/nao-existe").status_code)
resposta = cliente.post("/sobre")
print(resposta.status_code, resposta.json())
404
405 {'detail': 'Method Not Allowed'}
What FastAPI logged
In addition to its three routes, FastAPI added documentation pages. You can list everything that is registered:
print([rota.path for rota in app.routes])
['/openapi.json', '/docs', '/docs/oauth2-redirect', '/redoc', '/', '/sobre', '/usuarios']
Documenting the routes
The parameters of the decorator and the function's docstring become text in the documentation. tags groups the routes, summary gives a short title and the docstring provides the long description:
@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.
Testing in Swagger
In /docs, click on the route, then on Try it out and on Execute. The page shows the called address, the response body, and the status code. Routes GET can also be tested directly in the browser. The routes POST, PUT and DELETE cannot: the browser only sends GET when you type an address, and for the other verbs, you use Swagger, the curl or a tool like Postman.
Why JSON?
The purpose of an API is to exchange data between programs. JSON is lightweight, readable, and understood by almost every language, which is why it is the standard format for FastAPI. What your function returns (dictionaries, lists, Pydantic models) is automatically converted to JSON.
Exercise 1
A products route
Add GET /categorias, which returns the list ["livros", "jogos", "música"], and check the status and content.