1 现代网络
曾几何时,网络小而简单。开发者们把 PHP、HTML 和 MySQL 调用放到一个文件中,然后自豪地告诉大家去看看他们的网站,这样做非常有趣。但随着时间的推移,网络发展到了数以亿计,不对,是数以万亿计的页面,早期的游乐场变成了主题公园的元宇宙。
在本章中,我将指出一些与现代网络日益相关的领域:
- 服务和应用程序(API)
- 并发
- 层
- 数据
1.1 服务和应用程序(API)
网络是一个巨大的连接结构。尽管很多活动仍然发生在内容方面--HTML、JavaScript、图像等,但连接事物的应用程序编程接口(API)越来越受到重视。
通常情况下,网络服务负责处理低层次的数据库访问和中层业务逻辑(通常统称为后端),而JavaScript或移动应用程序则提供丰富的高层前端(交互式用户界面)。这些前端和后端世界变得更加复杂和多样化,通常需要开发人员专门从事其中一项工作。
这两个世界通过应用程序接口(API)相互对话。在现代网络中,API 的设计与网站本身的设计同等重要。API 是一种契约,类似于数据库模式。现在,定义和修改 API 已成为一项重要工作。
1.1.1 API种类
每个应用程序接口都定义了以下内容:
- 协议: 控制结构
- 格式: 内容结构
随着技术的发展,从孤立的机器到多任务系统,再到网络服务器,已经开发出多种API方法。你可能会在某一时刻遇到其中的一种或多种:
- 在联网之前,API通常意味着非常紧密的连接,比如调用与应用程序使用相同语言的库的函数--例如,在数学库中计算平方根。
- 远程过程调用(RPC)的发明是为了调用同一台机器或其他机器上其他进程中的函数,就像调用应用程序中的函数一样。当前流行的例子是 gRPC。
- 消息传递(Messaging)在进程间通过管道发送小块数据。消息可以是类似动词的命令,也可以只是表示感兴趣的类似名词的事件。目前流行的消息传递解决方案包括 Apache Kafka、RabbitMQ、NATS和ZeroMQ等,从工具包到完整的服务器,种类繁多。
通信可以遵循不同的模式:
- 请求-响应: 如网络浏览器调用网络服务器。
- 发布-订阅(Publish-subscribe, or pub-sub):发布者发布消息,订阅者根据消息中的某些数据(如主题)对每条消息采取行动。
- 队列:与发布-订阅类似,但只有一个订阅者会抓取信息并对其采取行动。
其中任何一种都可与网络服务一起使用,例如,执行发送电子邮件或创建缩略图等缓慢的后端任务。
1.1.2 HTTP
伯纳斯-李为他的万维网提出了三个组成部分:
- HTML: 显示数据的语言
- HTTP: 客户端-服务器协议
- URLs: 网络资源的寻址方案
随着网络的发展,人们不断尝试,有些想法,比如 IMG 标签,在达尔文式的斗争中幸存了下来。随着需求越来越明确,人们开始认真地定义标准。
1.1.3 REST(ful)
罗伊-菲尔丁(Roy Fielding)的博士论文中有一章定义了表征状态转移(REST Representational State Transfer)--一种HTTP使用的架构风格。虽然经常被提及,但它在很大程度上被误解了。一种大致相同的RESTful已经发展起来,并在现代网络中占据主导地位。具有以下特点:
- 使用HTTP和客户端-服务器协议
- 无状态(每个连接都是独立的)
- 可缓存
- 基于资源
资源是可以区分和执行操作的数据。网络服务为其希望公开的每项功能提供一个端点--不同的URL和HTTP verb(操作)。端点也称为路由,因为它将URL路由到一个函数。
数据库用户对程序的 CRUD 缩写很熟悉:创建、读取、更新、删除。HTTP的动词也非常CRUD:
- POST: 创建(写)
- PUT: 完全修改(替换)
- PATCH: 部分修改(更新)
- GET: 获取(读取、检索)
- DELETE: 删除
客户端向RESTful端点发送请求时,数据包含在HTTP报文的以下内容:
- Headers
- URL 字符串
- 查询参数
- Body
HTTP响应会返回以下内容:
- 返回码:表示以下内容的整数状态代码:
- 1xx:信息,继续
- 2xx:成功
- 3xx:重定向
- 4xx:客户端错误
- 5xx:服务器错误
- Headers
- Body
1.1.4 JSON和API数据格式
前端应用程序可以与后端网络服务交换纯ASCII文本,但如何表达诸如事物列表之类的数据结构呢?
就在我们开始真正需要它的时候,JavaScript Object Notation(JSON)出现了--这又是一个简单的想法,却解决了一个重要的问题,而且事后看来是显而易见的。虽然J代表JavaScript,但其语法看起来也很像Python。
JSON在很大程度上取代了XML和SOAP等。
1.1.5 JSON:API
RESTful设计与JSON数据格式的结合现在已经非常普遍。但仍有一些回旋的余地,容易产生歧义和书呆子的争论。最近提出的JSON:API提议旨在稍微收紧规范。本书将使用松散的RESTful方法,但如果有重大争议,JSON:API或类似的严格规范可能会有用。
1.1.6 GraphQL
RESTful接口对于某些用途来说可能很麻烦。Facebook(现为 Meta)设计了图形查询语言(GraphQL)来指定更灵活的服务查询。我不会在本书中介绍GraphQL,但如果你发现RESTful设计无法满足你的应用需求,你可能想了解一下GraphQL。
参考资料
- 软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
- 本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
- python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
- Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
1.2 并发
我们希望减少以下情况:
- 延迟: 前期等待时间
- 吞吐量: 服务与其调用者之间每秒的字节数
并发一词并不意味着完全并行。多重处理并不是在同一纳秒内,在单个CPU中进行的。相反,并发主要是避免繁忙等待(CPU 闲置,直到有响应为止)。CPU速度很快,但网络和磁盘的速度却要慢上几千到几百万倍。因此,每当我们与网络或磁盘对话时,我们都不希望只是坐在那里干瞪眼,直到它做出响应。
正常的Python执行是同步的:按照代码指定的顺序一次执行一件事。有时我们想要异步:做一点一件事,然后做一点另一件事,再回到第一件事,以此类推。如果我们所有的代码都使用CPU来计算(CPU 受限),那就真的没有空闲时间来做异步了。但是,如果我们执行的任务需要CPU等待外部任务完成(I/O 绑定),我们就可以采用异步方式。
异步系统提供了一个事件循环:慢速操作的请求会被发送和记录,但我们不会占用CPU来等待它们的响应。相反,每次通过循环时都会立即进行一些处理,在此期间收到的任何响应都会在下一次循环中进行处理。
这样做的效果会非常显著。在本书的后面部分,您将看到 FastAPI 对异步处理的支持如何使其比典型的Web框架更快。
异步处理并不神奇。您仍需注意避免在事件循环中执行过多的 CPU 密集型工作,因为这会减慢所有工作的速度。在本书的后面,您将看到Python的async和await关键字的用法,以及FastAPI如何让您混合同步和异步处理。
1.3 分层
-
网络: 通过HTTP传输的输入/输出层,负责汇集客户端请求、调用服务层并返回响应
-
服务层: 业务逻辑,在需要时调用数据层
-
数据层: 访问数据存储和其他服务
-
模型: 所有层共享的数据定义
-
网络客户端:网络浏览器或其他HTTP客户端软件
-
数据库:数据存储,通常是SQL或NoSQL服务器
各层之间通过API进行对话。这些API可以是对独立Python模块的简单函数调用,也可以通过任何方法访问外部代码。正如我前面所展示的,这可以包括RPC、消息等。在本书中,我假设只有一个Web服务器,Python代码导入其他Python 模块。分离和信息隐藏由模块处理。
用户通过客户端应用程序和API看到的是网络层。我们通常说的是 RESTful 网络接口,包括URL以及JSON编码的请求和响应。但也可以在网络层旁边构建其他文本(或命令行界面,CLI)客户端。Python Web代码可以导入服务层模块,但不应导入数据模块。
服务层包含该网站所提供服务的实际细节。这一层本质上看起来像一个库。它导入数据模块来访问数据库和外部服务,但不应该知道细节。
数据层通过文件或客户端调用其他服务为服务层提供数据访问。也可能存在其他数据层,与单个服务层通信。
模型框不是一个实际的层,而是各层共享的数据定义源。如果在这些层之间传递内置的Python数据结构,则不需要模型。正如您将看到的,FastAPI包含的Pydantic可以定义具有许多有用特性的数据结构。
为什么要进行这些划分?原因有很多,其中之一就是每一层都可以
- 由专家编写。
- 单独测试。
- 替换或补充:您可能会添加第二个网络层,使用不同的应用程序接口(如 gRPC),以及网络层。
- 客户端 ⇔ 网络: JSON的RESTful HTTP
- Web ⇔ 服务: Models
- 服务 ⇔ 数据: Models
- 数据 ⇔ 数据库和服务: 特定应用程序接口
无论如何设计,这些都是要点:
- 分离特定领域的细节。
- 在各层之间定义标准的应用程序接口。
- 不要作弊,不要泄密。
有时,决定哪一层是代码的最佳归宿是一项挑战。例如,第 11 章探讨了身份验证和授权要求,以及如何将其作为 Web 和服务之间的额外层或其中一层来实现。软件开发有时既是艺术,也是科学。
1.4 数据
网络通常被用作关系数据库的前端,尽管已经发展出许多其他存储和访问数据的方式,如NoSQL或NewSQL数据库。
但是,除了数据库之外,机器学习(ML)--或称深度学习或人工智能--正在从根本上重塑技术格局。开发大型模型需要对数据进行大量处理,这在传统上被称为提取、转换、加载(ETL)。
作为一种通用的服务架构,网络可以帮助解决人工智能系统的许多繁琐问题。
1.5小结
网络使用许多应用程序接口,尤其是RESTful应用程序接口。异步调用可以提高并发性,从而加快整个流程。网络服务应用程序通常规模庞大,需要分层处理。数据本身已成为一个重要领域。所有这些概念都将在下一章的Python编程语言中得到阐述。
标签:HTTP,FastAPI,网络,现代,JSON,API,RESTful,客户端 From: https://www.cnblogs.com/testing-/p/18233134