"Dependency Injection" significa, en programación, que hay una forma para que tu código (en este caso, tus path operation functions) declare cosas que requiere para funcionar y usar: "dependencias".
Y luego, ese sistema (en este caso FastAPI) se encargará de hacer lo que sea necesario para proporcionar a tu código esas dependencias necesarias ("inyectar" las dependencias).
Esto es muy útil cuando necesitas:
Tener lógica compartida (la misma lógica de código una y otra vez).
Compartir conexiones a bases de datos.
Aplicar seguridad, autenticación, requisitos de roles, etc.
Esto es simplemente Python estándar, se llama "type alias", en realidad no es específico de FastAPI.
Pero como FastAPI está basado en los estándares de Python, incluyendo Annotated, puedes usar este truco en tu código. 😎
Las dependencias seguirán funcionando como se espera, y la mejor parte es que la información de tipos se preservará, lo que significa que tu editor podrá seguir proporcionándote autocompletado, errores en línea, etc. Lo mismo para otras herramientas como mypy.
Esto será especialmente útil cuando lo uses en una base de código grande donde usas las mismas dependencias una y otra vez en muchas path operations.
Como las dependencias también serán llamadas por FastAPI (igual que tus path operation functions), las mismas reglas aplican al definir tus funciones.
Puedes usar async def o def normal.
Y puedes declarar dependencias con async def dentro de def normales path operation functions, o dependencias con def dentro de async defpath operation functions, etc.
No importa. FastAPI sabrá qué hacer.
Nota
Si no lo sabes, revisa la sección Async: "¿Con prisa?" sobre async y await en la documentación.
Si lo piensas, las path operation functions se declaran para ser usadas cuando un path y una operation coinciden, y luego FastAPI se encarga de llamar a la función con los parámetros correctos, extrayendo los datos de la petición.
En realidad, todos (o la mayoría) de los frameworks web funcionan de esta misma manera.
Nunca llamas a esas funciones directamente. Son llamadas por tu framework (en este caso, FastAPI).
Con el sistema de Dependency Injection, también puedes decirle a FastAPI que tu path operation function también "depende" de algo más que debería ejecutarse antes de tu path operation function, y FastAPI se encargará de ejecutarlo e "inyectar" los resultados.
Otros términos comunes para esta misma idea de "dependency injection" son:
Se pueden construir integraciones y "plug-ins" usando el sistema de Dependency Injection. Pero de hecho, en realidad no hay necesidad de crear "plug-ins", ya que usando dependencias es posible declarar un número infinito de integraciones e interacciones que quedan disponibles para tus path operation functions.
Y las dependencias pueden crearse de una manera muy simple e intuitiva que te permite simplemente importar los paquetes de Python que necesitas, e integrarlos con tus funciones de API en un par de líneas de código, literalmente.
Verás ejemplos de esto en los próximos capítulos, sobre bases de datos relacionales y NoSQL, seguridad, etc.
Aunque el sistema jerárquico de dependency injection es muy simple de definir y usar, sigue siendo muy potente.
Puedes definir dependencias que a su vez pueden definir dependencias por sí mismas.
Al final, se construye un árbol jerárquico de dependencias, y el sistema de Dependency Injection se encarga de resolver todas estas dependencias por ti (y sus sub-dependencias) y proporcionar (inyectar) los resultados en cada paso.
Por ejemplo, digamos que tienes 4 endpoints de API (path operations):
/items/public/
/items/private/
/users/{user_id}/activate
/items/pro/
entonces podrías añadir diferentes requisitos de permisos para cada uno de ellos solo con dependencias y sub-dependencias: