Cuando creas una operación de ruta de FastAPI puedes normalmente devolver cualquier dato desde ella: un dict, una list, un modelo de Pydantic, un modelo de base de datos, etc.
Si declaras un Response Model FastAPI lo usará para serializar los datos a JSON, usando Pydantic.
Si no declaras un response model, FastAPI usará el jsonable_encoder explicado en JSON Compatible Encoder y lo pondrá en un JSONResponse.
También podrías crear un JSONResponse directamente y devolverlo.
Consejo
Normalmente tendrás mucho mejor rendimiento usando un Response Model que devolviendo un JSONResponse directamente, ya que de esa forma serializa los datos usando Pydantic, en Rust.
Puedes devolver una Response o cualquier subclase de esta.
Nota
El propio JSONResponse es una subclase de Response.
Y cuando devuelves una Response, FastAPI la pasará directamente.
No hará ninguna conversión de datos con modelos de Pydantic, no convertirá los contenidos a ningún tipo, etc.
Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de dato, sobrescribir cualquier declaración o validación de datos, etc.
También te da mucha responsabilidad. Tienes que asegurarte de que los datos que devuelves son correctos, en el formato correcto, que pueden serializarse, etc.
Como FastAPI no hace ningún cambio a una Response que devuelves, tienes que asegurarte de que sus contenidos estén listos para ello.
Por ejemplo, no puedes poner un modelo de Pydantic en un JSONResponse sin primero convertirlo a un dict con todos los tipos de datos (como datetime, UUID, etc) convertidos a tipos compatibles con JSON.
Para esos casos, puedes usar el jsonable_encoder para convertir tus datos antes de pasarlos a una respuesta:
También podrías usar from starlette.responses import JSONResponse.
FastAPI proporciona las mismas starlette.responses que fastapi.responses solo como una conveniencia para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette.
El ejemplo anterior muestra todas las partes que necesitas, pero aún no es muy útil, ya que podrías haber devuelto el item directamente, y FastAPI lo pondría en un JSONResponse por ti, convirtiéndolo a un dict, etc. Todo eso por defecto.
Ahora, veamos cómo podrías usar eso para devolver una respuesta personalizada.
Como eso sucederá del lado de Rust, el rendimiento será mucho mejor que si se hiciera con Python regular y la clase JSONResponse.
Al usar un response_model o tipo de retorno, FastAPI no usará el jsonable_encoder para convertir los datos (lo cual sería más lento) ni la clase JSONResponse.
En su lugar, toma los bytes JSON generados con Pydantic usando el response model (o tipo de retorno) y devuelve una Response con el media type correcto para JSON directamente (application/json).
Puedes ver en secciones posteriores cómo usar/declarar estas Responses personalizadas mientras se sigue teniendo conversión automática de datos, documentación, etc.