Cuando necesitas enviar datos desde un cliente (digamos, un navegador) a tu API, los envías como un cuerpo de petición.
Un cuerpo de petición son los datos enviados por el cliente a tu API. Un cuerpo de respuesta son los datos que tu API envía al cliente.
Tu API casi siempre tiene que enviar un cuerpo de respuesta. Pero los clientes no necesariamente necesitan enviar cuerpos de petición todo el tiempo, a veces solo solicitan una ruta, quizás con algunos parámetros de query, pero no envían un cuerpo.
Para declarar un cuerpo de petición, usas modelos de Pydantic con todo su poder y beneficios.
Nota
Para enviar datos, deberías usar uno de: POST (el más común), PUT, DELETE o PATCH.
Enviar un cuerpo con una petición GET tiene un comportamiento indefinido en las especificaciones, sin embargo, está soportado por FastAPI, solo para casos de uso muy complejos/extremos.
Como está desaconsejado, la documentación interactiva con Swagger UI no mostrará la documentación del cuerpo cuando se usa GET, y los proxies intermedios podrían no soportarlo.
Al igual que al declarar parámetros de query, cuando un atributo del modelo tiene un valor por defecto, no es requerido. De lo contrario, es requerido. Usa None para hacerlo solo opcional.
Por ejemplo, este modelo de arriba declara un "object" JSON (o Python dict) como:
En tu editor, dentro de tu función obtendrás type hints y completado en todas partes (esto no pasaría si recibieras un dict en lugar de un modelo de Pydantic):
También obtienes chequeos de errores para operaciones de tipo incorrecto:
Esto no es por casualidad, todo el framework fue construido alrededor de ese diseño.
Y fue probado exhaustivamente en la fase de diseño, antes de cualquier implementación, para asegurar que funcionaría con todos los editores.
Hubo incluso algunos cambios en el propio Pydantic para soportar esto.
Las capturas de pantalla anteriores fueron tomadas con Visual Studio Code.
Pero obtendrías el mismo soporte del editor con PyCharm y la mayoría de los otros editores de Python:
Puedes declarar parámetros de ruta y cuerpo de petición al mismo tiempo.
FastAPI reconocerá que los parámetros de la función que coinciden con parámetros de ruta deben ser tomados de la ruta, y que los parámetros de la función que se declaran como modelos de Pydantic deben ser tomados del cuerpo de la petición.
Los parámetros de la función serán reconocidos de la siguiente manera:
Si el parámetro también está declarado en la ruta, se usará como un parámetro de ruta.
Si el parámetro es de un tipo singular (como int, float, str, bool, etc) se interpretará como un parámetro de query.
Si el parámetro se declara como de tipo de un modelo de Pydantic, se interpretará como un cuerpo de petición.
Nota
FastAPI sabrá que el valor de q no es requerido por el valor por defecto = None.
El str | None no es usado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de = None.
Pero añadir las anotaciones de tipo permitirá que tu editor te dé mejor soporte y detecte errores.