在构建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镜像应该没有问题。

广告
将在 10 秒后关闭
bannerAds