翼度科技»论坛 编程开发 python 查看内容

FastAPI-9 服务层

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
9 服务层

本章阐述了服务层,即中间层。
9.1 定义服务

服务层是网站的核心,它接收来自多个来源的请求,访问作为网站DNA的数据,并返回响应。
常见的服务模式包括以下组合:

  • 创建/检索/更改(部分或全部)/删除
  • 一件事/多件事
    在 RESTful 路由器层,名词是资源。在本书中,我们的资源最初将包括隐形生物(想象中的生物)和人(隐形生物探险家)。
以后,我们还可以定义类似的相关资源:

  • 地点
  • 事件(如探险、目击等)
9.2 布局

以下是当前的文件和目录布局:
  1. main.py
  2. web
  3. ├── __init__.py
  4. ├── creature.py
  5. ├── explorer.py
  6. service
  7. ├── __init__.py
  8. ├── creature.py
  9. ├── explorer.py
  10. data
  11. ├── __init__.py
  12. ├── creature.py
  13. ├── explorer.py
  14. model
  15. ├── __init__.py
  16. ├── creature.py
  17. ├── explorer.py
  18. fake
  19. ├── __init__.py
  20. ├── creature.py
  21. ├── explorer.py
  22. └── test
复制代码
9.3 函数

让我们从 creature.py 开始。在这一点上,explorer.py 的需求几乎相同,我们可以借用几乎所有的东西。我们很想编写一个服务文件来处理这两个文件,但几乎不可避免的是,在某些时候我们需要以不同的方式处理它们。
另外,在这一点上,服务文件几乎就是一个直通层。在这种情况下,一开始就增加一些额外的结构,以后就会有所回报。就像第8章中的 web/creature.py和web/explorer.py,我们将为这两个文件定义服务模块,并暂时将它们与相应的假数据模块挂钩。
service/creature.py
  1. from models.creature import Creature
  2. import fake.creature as data
  3. def get_all() -> list[Creature]:
  4.     return data.get_all()
  5. def get_one(name: str) -> Creature | None:
  6.     return data.get(id)
  7. def create(creature: Creature) -> Creature:
  8.     return data.create(creature)
  9. def replace(id, creature: Creature) -> Creature:
  10.     return data.replace(id, creature)
  11. def modify(id, creature: Creature) -> Creature:
  12.     return data.modify(id, creature)
  13. def delete(id, creature: Creature) -> bool:
  14.     return data.delete(id)
复制代码
service/explorer.py
  1. from models.explorer import Explorer
  2. import fake.explorer as data
  3. def get_all() -> list[Explorer]:
  4.     return data.get_all()
  5. def get_one(name: str) -> Explorer | None:
  6.     return data.get(name)
  7. def create(explorer: Explorer) -> Explorer:
  8.     return data.create(explorer)
  9. def replace(id, explorer: Explorer) -> Explorer:
  10.     return data.replace(id, explorer)
  11. def modify(id, explorer: Explorer) -> Explorer:
  12.     return data.modify(id, explorer)
  13. def delete(id, explorer: Explorer) -> bool:
  14.     return data.delete(id)
复制代码
9.4 测试

现在,代码库正在逐渐充实,是引入自动测试的好时机,让我们创建一些目录:

  • test:顶级目录,与web, service, data和model目录并列。

    • unit: 测试单个函数,但不跨层。

      • web: 网络层单元测试。
      • service: 服务层单元测试。
      • data:数据层单元测试。


  • full: 也称为端到端或合约测试,这些测试同时跨越所有层。它们涉及网络层的 API 端点。
这些目录有test_前缀或_test 后缀,供pytest使用 。
在测试之前,需要对 API 的设计做出一些选择。如果找不到匹配的 Creature 或 Explorer,get_one() 函数应该返回什么?可以返回 None,或者引发异常。没有一个内置的Python异常类型可以直接处理缺失值:

  • TypeError可能是最接近的,因为 None与Creature 是不同的类型。
  • ValueError 更适用于给定类型的错误值,但我想你也可以说,向 get_one(id)传递一个缺失的字符串 id 也符合条件。
  • 如果你真的需要,也可以定义自己的MissingError。
test/unit/service/test_creature.py
  1. from model.creature import Creature
  2. from service import creature as code
  3. sample = Creature(name="yeti",
  4.         country="CN",
  5.         area="Himalayas",
  6.         description="Hirsute Himalayan",
  7.         aka="Abominable Snowman",
  8.         )
  9. def test_create():
  10.     resp = code.create(sample)
  11.     assert resp == sample
  12. def test_get_exists():
  13.     resp = code.get_one("yeti")
  14.     assert resp == sample
  15. def test_get_missing():
  16.     resp = code.get_one("boxturtle")
  17.     assert data is None
复制代码
执行:
  1. $ pytest -v test/unit/service/test_creature.py
  2. test_creature.py::test_create PASSED                         [ 16%]
  3. test_creature.py::test_get_exists PASSED                     [ 50%]
  4. test_creature.py::test_get_missing PASSED                    [ 66%]
  5. ======================== 3 passed in 0.06s =========================
复制代码

参考资料

9.5 其他服务层内容

我们现在正处于堆栈的中间部分--真正定义网站目的的部分。到目前为止,我们只用它将网络请求转发到(下一章的)数据层。
到目前为止,本书以迭代的方式开发了网站,为今后的工作打下了最基本的基础。当你对你所拥有的、你所能做的以及用户可能需要的有了更多了解后,你就可以进行扩展和尝试。有些想法可能只对大型网站有益,但这里有一些技术性的网站辅助想法:

  • Logging
  • Metrics
  • Monitoring
  • Tracing
9.5.1 Logging

FastAPI会记录每次对端点的API调用,包括时间戳、方法和 URL,但不会记录通过正文或标头传递的任何数据。
9.5.2 指标、监控和可观察性

如果你运行一个网站,你可能想知道它的运行情况。对于 API 网站,你可能想知道哪些端点正在被访问、有多少人在访问等等。对这些因素的统计称为度量,收集度量是监控或可观察性。
时下流行的度量工具包括用于收集度量数据的Prometheus和用于显示度量数据的Grafana。

9.5.3 跟踪

您的网站性能如何?常见的情况是,度量指标总体良好,但某些地方或某些地方的结果令人失望。或者整个网站一团糟。无论哪种情况,有一个工具可以测量 API 调用从头到尾所需的时间--不仅是整体时间,还包括每个中间步骤的时间,这非常有用。如果某项工作进展缓慢,就可以找到链条中的薄弱环节。这就是跟踪。
一个新的开源项目采用了早期的跟踪产品(如 Jaeger),并将其命名为 OpenTelemetry。它有一个Python API,并至少与FastAPI 进行了一次集成。
9.5.4 其他

除此以外,我们的域密码和与之相关的任何内容又是怎样的呢?除了探索者和生物的基本细节外,你还想做什么?你可能会想出需要修改模型和其他层的新想法。以下是一些你可以尝试的想法:

  • 探险者与他们寻找的生物的链接
  • 目击数据
  • 探险
  • 照片和视频
  • 大脚野人马克杯和T恤衫

9.6 小结

在本章中,你复制了网络层中的一些函数,并移动了它们所使用的假数据。目的是启动新的服务层。到目前为止,这个过程都是按部就班地进行的,但在此之后,它还会不断发展和变化。下一章将构建最终的数据层,形成一个真正的实时网站。

来源:https://www.cnblogs.com/testing-/p/18242828
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具