LoginSignup
18
16

More than 3 years have passed since last update.

GolangでGraphQLサーバを組む際に必要になりそうなチェックリスト

Last updated at Posted at 2019-12-06

1.12時代に書いたメモなので2019-12-06現在最新ver(1.13)の状態には合わないかもしれないけど一応忘備録として公開しておく

このメモに書いた内容はGitHubにboilerplateとしてまとめてある

ここで挙げられたライブラリの基本的な選定の基準としては一つのライブラリであまり多くのことをやろうとせずUNIX哲学的にシンプルに一つの責務のみをこなし他ライブラリとのinteroperationがしやすいものを選ぶという感じ

GoでGraphQLサーバを実装する上で必要になりそうなチェックリストとその対策

  • GraphQL
  • ORM
  • 認証
  • 認可
  • ルーティング
  • DB
  • バリデーション
  • セキュリティ (CSRF)
  • マイグレーション
  • ロギング
  • テスト (E2E, Unit)
  • ドキュメンテーション
  • ページング
  • モジュール化
  • Fixture
  • キューイング
  • ホットリロード
  • i18n
  • パッケージング
  • デプロイ

環境

  • go 1.12
  • gqlgen
  • chi

Router

Chiを使う
gqlgen公式でサンプルとして紹介されているが標準インターフェースのhttpパッケージでやり取りしてるので相互運用性がよい

GraphQL

gqlgenを使う

そのまま使うとN+1クエリが出てしまうのでdataloadenでクエリをまとめる。仕組みとしてはdataloadenが1msほどwaitしてクエリをまとめてN+1クエリをIN句を使ったクエリに変換している

ORM

sqlboilerを使う

認証

JWTで行う
chiのmiddlewareのjwt-authを使う
今回はトークンのRevokeは要件にないので一旦は問題なし

認可

JWTは本人性の確認のみなので認可は別途実装する必要がある
おおざっぱな認可はGqlgenのdirectiveを使う
詳細な認可はcasbinでRBACで認可を行う

@hasRole(role: ADMIN)

問題: 管理画面系のクエリ、Mutationはどうするか
/queryという同一のエンドポイントで管理画面用のクエリを別に用意する?
クエリ一覧がわかりづらくならないか

type Query {
  hero(id: Int): Hero
  droid(id: Int): Droid
}

ルーティング

GraphQLなので基本的には必要ないが一部分APIにしたいというような場合はchiのルーティングを使う

DB

ORMはsqlboilerを使う

バリデーション

GraphQLの型チェックはする
+カスタムのバリデータとしてozzo-validationなど使う

出来れば宣言的にバリデーションしたいがsql-boilerが動的にタグを生成していじってはいけないのでタグに埋め込む形のバリデータと少し相性が悪い

各modelのStructにValidateメソッドを生やしてその中で各フィールドのバリデーション、任意のタイミングでValidateメソッドを実行

セキュリティ

chiのmiddlewareを使う

migration

sql-migrateを使う
packr でのマイグレーションファイルのマウントに対応してたので

これによりシングルバイナリでサーバにポン置きでmigrationを実行出来る

ロギング

logrusでJSON形式で出力

テスト (E2E)

unitはtestify
graphqlクライアントとしてgo-graphqlでリクエストする
E2Eはdreddなど別途ツールを使ってもいいかも

ドキュメンテーション

GraphQLのIntrospectionで提供
開発サーバにplaygroundを埋め込み
本番環境では無効にする

ページング

Cursor-based pagination

モジュール化

go 1.11より導入された Go module で管理

Fixture

事前に作成したSQLを直接読み込ませるか
https://github.com/zhulongcheng/testsql

gp-sqlmockで仮想的にmockデータを作りそれでやりとりさせるか

キューイング

外部にキューイング用のバックエンドを用意する想定

redisをバックエンドにmachineryを使う

ホットリロード

realize

2019-03-21現在 Go 1.12のGo Modulesに対応していなかったのでgo.modファイルを使う場合は多少設定ファイルをいじる必要がある

i18n

go-i18nで多言語化対応

パッケージング

packrを使いマイグレーションファイルなどの静的ファイルをバイナリにembedする

デプロイ

packrでシングルバイナリにしたあとalpineイメージにビルド後のバイナリをADDしてデプロイ用のイメージ作成
scratchでもいいけどなんだかんだでコンテナ内でapkコマンド叩けると嬉しい場面が多いのでそこまでシビアにイメージサイズ絞りたいとかでなければalpineで問題ないと思う

18
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
16