Go语言实战 : API服务器 (2) 运行流程 | 小册免费学

281 阅读5分钟

1.API服务器的总流程

分为两步:

  1. 启动API服务器
  2. API服务器对HTTP请求进行处理

2.API服务器启动流程

  1. 解析配置文件,利用配置文件完成对服务器的初始化配置
  2. 初始化logger,开启日志记录
  3. 与数据库建立连接
  4. 设置http连接(例如设置响应头,注册路由,注册中间件)

3.HTTP 请求处理流程

  1. DNS域名解析 DNS的过程是这样的:首先我们知道我们本地的机器上在配置网络时都会填写DNS,这样本机就会把这个url发给这个配置的DNS服务器,如果能够找到相应的url则返回其ip,否则该DNS将继续将该解析请求发送给上级DNS,整个DNS可以看做是一个树状结构,该请求将一直发送到根直到得到结果。现在已经拥有了目标ip和端口号,这样我们就可以打开socket连接了。

  2. 建立连接 当我们输入这样一个请求时,首先要建立一个socket连接,因为socket是通过ip和端口建立的(tcp链接),所以之前还有一个DNS解析过程,把域名变成ip,如果url里不包含端口号,则会使用该协议的默认端口号。

  3. 发送请求 连接成功建立后,开始向web服务器发送请求,这个请求一般是GET或POST命令(POST用于FORM参数的传递)。GET命令的格式为GET 路径/文件名 HTTP/1.0( 文件名指出所访问的文件,HTTP/1.0指出Web浏览器使用的HTTP版本)

现在可以发送GET命令:GET /mydir/index.html HTTP/1.0

  1. 接收请求 API服务器收到这个请求,进行处理,首先根据 HTTP 请求行的信息来解析到 HTTP 方法和路径,之后根据 API 服务器注册的路由信息(大概可以理解为:HTTP 方法 + 路径和具体处理函数的映射)找到具体的处理函数。

  2. 处理请求 在接收到请求之后,API 通常会解析 HTTP 请求报文获取请求头和消息体,然后根据这些信息进行相应的业务处理,HTTP 框架一般都有自带的解析函数,只需要输入 HTTP 请求报文,就可以解析到需要的请求头和消息体。

例如对应刚刚的get请求,就会解析出请求的消息头和消息体,然后API服务器就根据解析出来的内容,从它的文档空间中搜索子目录mydir的文件index.html。如果找到该文件,Web服务器把该文件内容传送给相应的Web浏览器。

业务处理主要可以分为:

  1. 包含对数据库的操作:需要访问数据库(增删改查),然后获取指定的数据,对数据处理后构建指定的响应结构体,返回响应包。
  2. 不包含对数据库的操作:进行业务逻辑处理后,构建指定的响应结构体,返回响应包。

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能够执行下列操作:

  1. 查找、加载和反序列化JSON、TOML、YAML、HCL、INI、envfile和Java properties格式的配置文件;
  2. 提供一种机制为你的不同配置选项设置默认值;
  3. 提供一种机制来通过命令行参数覆盖指定选项的值;
  4. 提供别名系统,以便在不破坏现有代码的情况下轻松重命名参数;
  5. 当用户提供了与默认值相同的命令行或配置文件时,可以很容易地分辨出它们之间的区别;