在构建Golang的GraphQL服务器时可能需要的检查清单
由于该备忘录是在1.12时代编写的,所以可能不适用于最新的版本(1.13)。但为了备忘起见,还是公开出来吧。
我在这个备忘录中写下的内容已经整理在GitHub上作为样板。
- shufo/go-graphql-boilerplate: A boilerplate for creating GraphQL server with Go
在选择这些列出的库时,基本的选择标准是选择一个库,不要试图在一个库里做太多事情。而是按照UNIX哲学的思想,选择一个只完成单一职责的库,以便轻松与其他库进行互操作。
在实现Go的GraphQL服务器时可能需要的检查清单和相关对策。
GraphQL
ORM
認証
認可
ルーティング
DB
バリデーション
セキュリティ (CSRF)
マイグレーション
ロギング
テスト (E2E, Unit)
ドキュメンテーション
ページング
モジュール化
Fixture
キューイング
ホットリロード
i18n
パッケージング
デプロイ
环境
-
- go 1.12
-
- gqlgen
- chi
路由器
使用Chi
尽管gqlgen官方使用http包的标准接口作为示例介绍,但它与Chi可相互操作,具有良好的互操作性。
GraphQL 图形查询语言
使用gqlgen
为了避免出现N+1查询,使用dataloaden来合并查询。其原理是dataloaden等待大约1毫秒,将查询合并为使用IN子句的N+1查询。
ORM可以将数据从关系型数据库中映射到对象模型,从而简化了在应用程序中处理数据库的过程。
使用SQLBoiler
確認身份
在中国本土使用JWT进行操作
使用chi的中间件jwt-auth
由于本次不需要撤销令牌,所以暂时没有问题。
同意
JWT只是用于身份验证,还需要单独实施授权。
可以使用Gqlgen指令实现大致的授权。
可以使用casbin进行详细的RBAC授权。
@hasRole(role: ADMIN)
问题:管理界面的查询和修改该如何处理?
是否需要在/query这个统一的末端点上另外准备一个用于管理界面的查询?
会不会让查询列表变得难以理解?
type Query {
hero(id: Int): Hero
droid(id: Int): Droid
}
路由
由于是GraphQL,基本上不需要,但如果想将某些部分作为API,则可以使用chi的路由。
数据库
使用ORM工具时,我们会选择sqlboiler。
验证
在GraphQL中进行类型检查时,可以使用自定义的验证器,例如ozzo-validation。
如果我想要对它进行声明验证,在它们出现时,但是由于 SQL-Boiler 会动态生成并且不允许修改标签,所以使用标签嵌入形式的验证器与之不太兼容。
针对每个model的Struct添加一个Validate方法,在其中对每个字段进行验证,并在任意时机执行Validate方法。
安全
使用chi的中间件
- cors
迁徙
→ 我们能够通过使用 packr 将 sql-migrate 与迁移文件一起进行挂载。
这样一来,我们可以通过单一二进制文件将迁移操作直接放置在服务器上。
记录
使用logrus以JSON格式进行输出。
考试 (E2E)
单位可以作证
可以使用go-graphql作为graphql客户端请求
也可以使用其他工具如dredd来进行端对端测试
文档化
在GraphQL的内省功能中提供
将playground嵌入到开发服务器中
在生产环境中禁用
分页
基于游标的分页
模块化
使用Go 1.11引入的Go模块进行管理
装置
是否要直接读取之前创建的SQL文件?你可以在 https://github.com/zhulongcheng/testsql 中找到。
使用gp-sqlmock在虚拟环境中创建模拟数据,并进行交互。
排队
预计为队列排队准备一个后端系统
使用machinery作为redis的后端
热加载
意识到
目前(2019-03-21),由于没有支持Go 1.12的Go Modules,如果要使用go.mod文件,则需要稍微调整一下配置文件。
国际化
使用go-i18n进行多语言支持
包装
使用Packr工具将迁移文件和静态文件等嵌入二进制文件中。
部署
将打包程序packr生成的单一二进制文件添加到alpine镜像中,创建一个用于部署的镜像。也可以使用scratch镜像,但是在容器内部访问apk命令非常方便,所以除非有非常严格压缩镜像大小的要求,否则使用alpine镜像应该没有问题。