[英]How to structure a FastAPI app that calls other API's
我看过这篇文章: What are the best practices for structuring a FastAPI project?
这是一个很好的基线,但我想知道调用第 3 方 API 的位置在哪里。 在此处的 v1 文件夹中创建一个服务文件夹是否有意义。 然后将模块放入其中以处理第 3 方 API。
没有真正最好的方法。 这完全取决于您的用例和个人偏好/实践。 话虽如此,我可以给你几个选择:
在应用程序根目录内的单独子模块中开发 class、方法或您可能需要的任何内容。 根据需要命名此子模块(服务、实用程序、第 3 方等)。 最后,只要它对您和参与该项目的其他人来说是一个有意义的名称,它并没有那么重要。
如果此实现是 static,那么您可以使用 go,只需执行简单的导入即可在特定的 controller 中使用它。
另一方面,如果您需要创建一个 class object 实例,它应该可以在整个应用程序中访问,并且您不希望每次在 controller 中执行它时都创建一个新的 object(例如,您不希望打开 X HTTP 客户端会话)。 那么FastAPI 事件处理程序就可以派上用场了:
您可以定义需要在应用程序启动之前或应用程序关闭时执行的事件处理程序(函数)。 这些函数可以用 async def 或 normal def 声明。
为了在我的fastapi-mvc-template启动事件中给你一个更好的例子,我创建了 Redis 和 Aiohttp class object 实例:
async def on_startup():
RedisClient.open_redis_client()
AiohttpClient.get_aiohttp_client()
async def on_shutdown():
await RedisClient.close_redis_client()
await AiohttpClient.close_aiohttp_client()
然后可以在任何 controller 中使用,而无需在每次调用 API 方法时都创建它们:
from fastapi_mvc_template.app.utils.redis import RedisClient
from fastapi_mvc_template.app.utils.aiohttp_client import AiohttpClient
response = RedisClient.get("Key")
response = AiohttpClient.get("http://foo.bar")
如果用于处理 3rd 方 API 的实现大于几个文件/类。 那么也许值得考虑将其作为单独的 Python package 编写,或者使用适用于您的语言的第 3 方实现(如果有的话)。 但是,您应该在需求中注意这个依赖版本。 理想情况下硬编码或锁定到补丁版本(例如 1.1.x)。
恕我直言,一个 API 调用另一个 API 可能不是最好的方法。 每次对 API 进行更改时,为了向后兼容,您应该对其进行版本控制。 我估计第 3 方 API 供应商会在改进他们的供应商时做同样的事情。 而现在,如果你开始快速增长和扩展,你可能会得到一个兼容性矩阵 web ,它非常复杂,甚至蜘蛛侠都会头疼:)。
所谓的远程过程调用 (RPC) + 协议缓冲区可能是更好的方法。 目前CNCF孵化的主要框架有一个: gRPC
gRPC 的好处:
当然,第三方服务可能不提供该选项。 N.netheless,值得研究这个话题,因为它的好处和现在越来越受欢迎。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.