はじめに
これは 2020/11/28 の Hasura Japan User Group 3 という勉強会で発表する内容です。
今日話すこと
- Hasuraを本番運用している話
- Hasuraとセキュリティ
の大きく二部構成で話します。
詳しく聞きたいことがあれば途中でも掘り下げていただければと思います。
自己紹介
- しんのき @konoki_nannoki
- React歴3.5年、TypeScript歴3年、GraphQL歴2年、Hasura歴1年
- 8月のGraphQL Tokyo MeetupでHasuraについて喋りました Hasura とは何者か メリット・デメリット - Speaker Deck
- WASD Inc. CTO
- デジちゃいむというサービスを作っています デジちゃいむ - 店舗接客を革新するクラウドチャイム
- 現在はアミューズメント施設様の導入が多く、最近は飲食店様やホームセンター様の導入事例が徐々に出てきました
- アミューズメント業界のご縁もあり週間ファミ通様に取材されました
本日発売の週刊ファミ通の巻末特集で弊社とデジちゃいむに関するインタビュー記事が掲載されました!🎉
— しんのき (@konoki_nannoki) 2020年11月12日
自分たちのできることをがむしゃらにやっていたら、このように取り上げていただいて、とても励みになります☺️ pic.twitter.com/HSk5ta43JB
これまでの道のり
- 5月 βリリース
- Amplify Auth
- Hasuraパーミッション見直し
- 6月 iOS/Androidアプリリリース
- React Native(Expo)
- 8月 正式サービス開始
- クレカ課金はStripeを採用
- 9月 チャット機能
- GraphQL Subscription
- 10月 画像添付機能
- Amplify Storage
- 11月 位置情報機能
Hasuraを本番運用している話
国内スタートアップのHasura採用例(勝手に参照)
- WASD Inc.
- βリリース時のnote WASD Inc.という会社でCTOをやっています|Yudai Shinnoki|note
- ログラスさん
- diniiさん
プロジェクト構成
- monorepo構成
- 前回のKeiさんの資料が非常にわかりやすいです Hasuraを使ったフルスタックアプリケーション開発のための基盤構築
- 1つのリポジトリにプッシュすると3つのWebフロントエンド(後述)がVercelにデプロイされる
- Ignored Build Step を設定すると、対象のディレクトリが変更されていない場合はビルドがスキップされる
- GraphQL Code Generator(codegen)はYarn Workspacesのルートにインストールしている
ロールとパーミッションの設定
- 現在、user(ログイン済)、anonymous(匿名)、support(運営)の3ロール(とadminロール)
- 今のところロール毎にWebフロントエンドが分かれる形に落ち着いている
- 1つのApolloClient
x-hasura-role
を動的に切り替えるのは 🙅♀️- キャッシュが混ざって見えないはずのデータが見えてしまったり不具合の温床になる
- ApolloClient(というよりApolloProvider)ごと分離するべき
- そこまでやるのであればプロジェクトごとまるっと分けてしまったほうが良い
- ロール = 境界づけられたコンテキスト として、明確に分けることができるはず
- 公式ドキュメントのauthor-reviewer-editorのサンプル はミスリードだと思う
- codegenの設定に
x-hasura-role
をセットするのは非常にオススメ
schema: - http://localhost:8080/v1/graphql headers: x-hasura-admin-secret: myadminsecretkey x-hasura-role: user
Hasuraを使っててよかったこと
- スケールに合わせてインフラを選びやすい
- Hasura: Heroku → Fargate(isolated) → Fargate(private)
- Fargateに移したときにガチガチにprivate network内に閉じるようにしたら辛かったので少しゆるくした
- Hasura Cloud使ってみたいけど英語サポートとやりとりするコストを考え踏みとどまっている
- DB: Heroku Hobby → Amazon RDS for PostgreSQL → Amazon Aurora PostgreSQL
- Serverless Function: Serverless Framework → AWS CDK → Serverless Framework
- デプロイ遅かったので出戻りした
- Frontend: S3+CloudFront→ Amplify Console → Vercel
- コスト重視から機能重視に徐々に移行できた
- Next.jsを採用するために最近Vercelに移行
- monorepo対応や環境変数まわりの改善に合わせて移行できてよかった
- Hasura: Heroku → Fargate(isolated) → Fargate(private)
- 日々の開発にジョインするための学習コストが非常に低い
docker-compose up
とyarn start
だけで環境が立ち上がる
Hasuraを使っててつらいこと
- 日々の開発以上のことを勉強しようとすると覚えるべきことが多い
- パーミッションの設定には頭をつかうしレビューも難しいのでどうしても属人化する
- 後述するセキュリティまわり等は情報が少ないので自分たちで工夫するしかない
現状の感触
- もともと辛くなったらバックエンド書こうと考えていたけど、今はHasuraで突っ走れそうな気がしている
- どこでパフォーマンスの問題に直面するのかが未知
- DBで障害を起こすと辛いので割と早い段階からAurora db.t3.mediumを採用している
- 初期にpollingで実装したところをsubscriptionに書き換えたいけど、websocketはネットワーク環境の影響を受けやすいので移行を踏みとどまっている(2ヶ月ほど)
Hasuraとセキュリティ
チェックリスト
- 公式のProduction Checklistに従って設定すれば大丈夫
- Production checklist | Hasura GraphQL Docs
- 最初から全てやろうと思うと大変なので、できるところからやっていきましょう
- ただしパーミッションの設定についてはプロダクトに依るところがあるので、自分たちで責任をもってチェックする必要がある
- 大企業様のセキュリティチェックシートや脆弱性診断を通過しました
Actionsのパーミッション
- Actionsでは、ロールごとに許可/拒否の2種類しかない
- DBのデータをもとにパーミッションのようなことがやりたかったら、Action Handler内からHasuraにQueryを投げ返し、引っ張ってきたデータをもとにロジックを書く
- 基本的にAction Handlerは 1つのQuery → 何かしらのロジックや外部通信 → 1つのMutation になるようにする
- 複数の更新処理を1つのMutationにまとめることでトランザクションしてくれるので、1つのMutationにまとめるのが大原則
- GraphQLは前のMutationの結果を拾って次のMutationに渡すことができない(知ってたら教えて下さい)
- 奥の手としてDatabase Triggerを使う
- Remote Schemaの場合はどうなんでしょう(あまり使っていない)
データのバリデーション
varchar(n)
を使う(おすすめ)- PostgreSQLの
varchar(n)
型はtext
に文字数制限がついたもの(MySQLとは違う) - DBの定義に出てくるのでわかりやすい
- Hasura Console上の表示が微妙なのが残念...今後の改善に期待
- PostgreSQLの
- Check Constraints を使う
- 数値の大小や、カラム同士の比較が必要な場合
- 見通しがあまりよくないので、下の方法に寄せてしまったほうがよさそう
- ActionsやRemote Schema経由でデータを挿入する
- 複雑なロジックが必要な場合
- 何でもできる
実現できていないこと
- Admin Secretが外部に漏れたら好き勝手やられてしまう
- とはいえHasura ConsoleやMigrationがあるので、
x-hasura-admin-secret
を全て拒否するのは難しい - 特定のIP以外だったらロードバランサ側で
x-hasura-admin-secret
ヘッダーをドロップすることができればよさそう - システム側からも
x-hasura-admin-secret
を持ったリクエストが飛んでくるので、そちらの考慮も必要
- とはいえHasura ConsoleやMigrationがあるので、
- IP制限
- マルチテナントSaaSなので、テナント毎やユーザー毎にIP制限をかけられると嬉しい
- Auth Webhookで頑張ればいけなくもなさそうだけど、全てのクエリに対して毎回処理が走るのはしんどそう
- Hasura CloudのAPI limitsではこれはできないよね?API limits | Hasura GraphQL Docs
まとめ
- 0→1、1→10のフェーズのHasura採用は胸をはってオススメできる(パーミッションを理解している人が1人以上居る前提)
- ここから先どうスケールするかはまたどこかでご報告します
宣伝
- Hasura、TypeScript、Next.jsなスタックを実務で使ってみたいインターンや業務委託を募集しています!!
- しんのき @konoki_nannoki までリプやDMください!まずは気軽にお話しましょう
- フワッとした仕様を手を動かして形にしたい方大歓迎です
- Material UI、Storybook、テストの知見があると嬉しいです
- ゲーム、ゲームセンターが好きな人は特に楽しめると思います
- 昨日も皆でAmong Usやりました