继续
数据库开发
- 使用 sqlc 生成代码后, 编写单元测试来测试生成的代码和自己写的 query 是否满足需求.
Web 开发 C3 RPC 和中间件
本章先看 Go 中如何手动实现中间件, 然后看社区提供的中间件解决方案 Gorilla handlers, 然后会开发 RPC 服务, 并看 RPC 框架.
中间件
中间件位于 router handler 的前端, 所有的请求都会先通过中间件管线再进入到 router, 所有的响应都从 router 发回到中间件管线. 总结起来:
- 预处理请求: 在请求到达 handler 前, 请求会经过中间件构成的请求处理管线.
- 后处理响应: 在 handler 生成响应后, 响应会经过处理管线, 再被发送给客户.
手动创建中间件
手动创建中间件管线时, 实际是创建 handler 的包裹器, 在注册 handler 前将 handler 包裹在里面注册, 这个时候就可以在 handler 执行前先执行中间件了.
这样的实现只是概念性的, 因为每个路径的 handler 都需要根据情况进行不同的包裹, 写的太啰嗦, 中间件的定义由于都是 handler 的包裹, 这样写起来也非常费劲.
不过有一个叫 alice 的库可以解决这样的问题.
使用 alice 创建中间件请求处理管线
alice 的 github 链接: https://github.com/justinas/alice
它可以将之前的包裹形式定义的中间件处理管线从下面的:
Middleware1(Middleware2(Middleware3(App)))
转换为这样的写法:
alice.New(Middleware1, Middleware2, Middleware3).Then(App)
社区提供的中间件集合
Gorilla handlers 提供了若干执行常见任务的中间件集合. Github 的链接为: https://github.com/gorilla/handlers
即便是结合 handlers 和 alice, 写法上仍然非常蛋疼. 更好的办法是选择一个成熟的 web 框架, 比如 Gin.
RPC
RPC 是远程过程调用的简称, 是一种分布式系统中的进程间通信机制. 通过 RPC 协议, 机器 A 可以调用机器 B 上的指定过程, 并且可以传递参数然后获取结果. RPC 还可以作为本地 IPC 或进程内跨语言通信的一种特殊形式, 比如 AppFlowy 里面用 gRPC 沟通 Rust 和 Flutter 侧.
RPC 通信时, 过程如下:
- 客户指定函数名称和需要发送的参数
- 客户将这些发送给服务器
- 服务器接收到函数名和参数
- 服务器执行对应函数
- 服务器将执行返回结果发送给客户
- 客户获取到结果并进行后续处理
在 Go 里面提供了两个库可以实现 RPC, 一个是 net/rpc, 还有一个是 net/rpc/jsonrpc.