1.API服务器的总流程
分为两步:
- 启动API服务器
- API服务器对HTTP请求进行处理
2.API服务器启动流程
- 解析配置文件,利用配置文件完成对服务器的初始化配置
- 初始化logger,开启日志记录
- 与数据库建立连接
- 设置http连接(例如设置响应头,注册路由,注册中间件)
3.HTTP 请求处理流程
-
DNS域名解析
DNS的过程是这样的:首先我们知道我们本地的机器上在配置网络时都会填写DNS,这样本机就会把这个url发给这个配置的DNS服务器,如果能够找到相应的url则返回其ip,否则该DNS将继续将该解析请求发送给上级DNS,整个DNS可以看做是一个树状结构,该请求将一直发送到根直到得到结果。现在已经拥有了目标ip和端口号,这样我们就可以打开socket连接了。 -
建立连接
当我们输入这样一个请求时,首先要建立一个socket连接,因为socket是通过ip和端口建立的(tcp链接),所以之前还有一个DNS解析过程,把域名变成ip,如果url里不包含端口号,则会使用该协议的默认端口号。 -
发送请求
连接成功建立后,开始向web服务器发送请求,这个请求一般是GET或POST命令(POST用于FORM参数的传递)。GET命令的格式为GET 路径/文件名 HTTP/1.0(
文件名指出所访问的文件,HTTP/1.0指出Web浏览器使用的HTTP版本)
现在可以发送GET命令:GET /mydir/index.html HTTP/1.0
-
接收请求
API服务器收到这个请求,进行处理,首先根据 HTTP 请求行的信息来解析到 HTTP 方法和路径,之后根据 API 服务器注册的路由信息(大概可以理解为:HTTP 方法 + 路径和具体处理函数的映射)找到具体的处理函数。 -
处理请求
在接收到请求之后,API 通常会解析 HTTP 请求报文获取请求头和消息体,然后根据这些信息进行相应的业务处理,HTTP 框架一般都有自带的解析函数,只需要输入 HTTP 请求报文,就可以解析到需要的请求头和消息体。
例如对应刚刚的get请求,就会解析出请求的消息头和消息体,然后API服务器就根据解析出来的内容,从它的文档空间中搜索子目录mydir的文件index.html。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。
业务处理主要可以分为:
- 包含对数据库的操作:需要访问数据库(增删改查),然后获取指定的数据,对数据处理后构建指定的响应结构体,返回响应包。
- 不包含对数据库的操作:进行业务逻辑处理后,构建指定的响应结构体,返回响应包。
4.REST Web 框架选择
要编写一个 RESTful 风格的 API 服务器,首先需要一个 RESTful Web 框架,选择 GitHub star 数最多的 Gin。采用轻量级的 Gin 框架,具有如下优点:
- 快速
基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
- 支持中间件
传入的 HTTP 请求可以由一系列中间件和最终操作来处理。例如:Logger,Authorization,GZIP,最终操作 DB。
- Crash 处理
Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!
- JSON 验证
Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
- 路由组
更好地组织路由。是否需要授权,不同的 API 版本…… 此外,这些组可以无限制地嵌套而不会降低性能。
- 错误管理
Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
- 内置渲染
Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
- 可扩展性
新建一个中间件非常简单
5.配置解决方案
Viper是适用于Go应用程序的完整配置解决方案。它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式,具有如下特性:
- 设置默认值
- 从JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件读取配置信息
- 实时监控和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)读取并监控配置变化
- 从命令行参数读取配置
- 从buffer读取配置
- 显式配置值
从上面这些特性来看,Viper 毫无疑问是非常强大的,而且 Viper 用起来也很方便,在初始化配置文件后,读取配置只需要调用 viper.GetString()、viper.GetInt() 和 viper.GetBool() 等函数即可。
Viper能够执行下列操作:
- 查找、加载和反序列化JSON、TOML、YAML、HCL、INI、envfile和Java properties格式的配置文件;
- 提供一种机制为你的不同配置选项设置默认值;
- 提供一种机制来通过命令行参数覆盖指定选项的值;
- 提供别名系统,以便在不破坏现有代码的情况下轻松重命名参数;
- 当用户提供了与默认值相同的命令行或配置文件时,可以很容易地分辨出它们之间的区别;