Slide 1

Slide 1 text

GraphQL "スキーマ設計基本方針"の案 その2

Slide 2

Slide 2 text

命名規則

Slide 3

Slide 3 text

型名はPascalCase, フィールド名は camelCase

Slide 4

Slide 4 text

イニシャリズム、アクロニムも先頭の文字だけ 大文字にする SSO や HTTP のような名前と相性が悪いコード生成ツールが ある。

Slide 5

Slide 5 text

enumはUPPER_SNAKE_CASEにする 統一されていることが重要

Slide 6

Slide 6 text

scalarを活用する

Slide 7

Slide 7 text

scalarを定義することで書式やルールをもつ値を表現すること ができる。

Slide 8

Slide 8 text

B/Eが得られるメリット (Go - gqlgenの場合)

Slide 9

Slide 9 text

変換処理を書くことで、リゾルバーでは変換されたデータを受 け取ることができる。

Slide 10

Slide 10 text

F/Eが得られるメリット (graphql-codegenの場合)

Slide 11

Slide 11 text

スキーマからmockデータを生成するライブラリで、scalarに 対するダミーデータのデータ形式を指定できたりする。

Slide 12

Slide 12 text

後方互換性を保つ

Slide 13

Slide 13 text

GraphQLの基本思想はバージョンレス。 少なくとも一度の更新でフィールドの非推奨化と削除を同時に 行ってはならない。

Slide 14

Slide 14 text

フィールドを非推奨化するには @deprecated ディレクティ ブを使用する。

Slide 15

Slide 15 text

MutationのInputとPayload

Slide 16

Slide 16 text

Mutationの引数はそれぞれ専用のInput1つに する?

Slide 17

Slide 17 text

古いRelayの仕様の名残らしく、あまりメリットはない。 長いものには巻かれろ(?)

Slide 18

Slide 18 text

Mutationはそれぞれ専用のPayloadを返す

Slide 19

Slide 19 text

大前提として、Mutationは更新されたリソースを返 すべき クライアントライブラリがキャッシュを自動的に更新すること ができる。

Slide 20

Slide 20 text

リソースをそのまま返してしまうと、追加で返したいフィール ドが増えた場合に破壊的変更となってしまう。 => 専用のPayload型を使おう

Slide 21

Slide 21 text

Mutationを多機能にしない

Slide 22

Slide 22 text

実装やメンテナンスのコストが跳ね上がるため、ひとつの Mutationに持たせる機能は1つだけになるようにする。

Slide 23

Slide 23 text

"データ型+操作(作成/更新/削除)"の単位でmutationを切ると 大変なことになる。

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

以下のようなクエリを書くことで、一つのクエリを使って選択 的なデータ更新を行うことはできる。 @include とは逆の @skip ディレクティブもある。

Slide 26

Slide 26 text

セキュリティ関連

Slide 27

Slide 27 text

GraphQLではクライアントが任意のクエリを投げることができ る。 ↓ 要求された全てのフィールドを解決しようとすると サーバーに想定外の負荷がかかってしまう場合がある

Slide 28

Slide 28 text

クエリの複雑性に制限をかける

Slide 29

Slide 29 text

クエリの複雑性=8

Slide 30

Slide 30 text

クエリをパースした後に複雑性(complexity)を計算する。 複雑性が一定以上であれば、フィールドの解決を一切行わずに エラーを返すことができる。

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

gqlgenでは以下のようにフィールド単位の複雑性の計算方法を 設定することができる。 mailAccounts フィールドは、解決するまで項目数がわか らない 仕様で上限が決まっている場合には、その上限いっぱいにデ ータを返すことを想定して計算する (あまりやりたくないパターン)

Slide 33

Slide 33 text

クエリの複雑性=24

Slide 34

Slide 34 text

ページネーションされるフィールドでは、ペー ジあたりの最大項目数を引数として受ける

Slide 35

Slide 35 text

アドレス帳の1ページ目にある連絡先を取得するクエリ。

Slide 36

Slide 36 text

引数としてページあたりの最大項目数を受けているため、クエ リから複雑性を導くことができる。

Slide 37

Slide 37 text

クエリの複雑性=202

Slide 38

Slide 38 text

ページあたりの項目数を引数にすることで、複雑性の計算が 簡単になる "ページあたりの項目数"の決定は本来F/Eの責務 スキーマでデフォルト値を記述することもできる B/Eでは有効な値の範囲を決めておく必要がある 範囲を示すディレクティブがあっても良い @range(min: 1, max: 200)

Slide 39

Slide 39 text

このようなクエリでも、複雑性を計算して受け入れるかどうか を合理的に判定することができる。

Slide 40

Slide 40 text

複雑性の閾値は計測しながら決めていくしかないようです。

Slide 41

Slide 41 text

Introspection/GraphiQL ぐ ら ふ ぃ か る の無効化

Slide 42

Slide 42 text

パブリックAPIでない限り、本番環境ではGraphiQLのようなプ レイグラウンドを公開するべきでない。 同様に、スキーマ情報を取得できるIntrospectionも無効化し ておく。 OWASP Cheat Sheet Series - GraphQL Cheat Sheet

Slide 43

Slide 43 text

エラーレスポンスに実装の情報が入り 込まないようにする

Slide 44

Slide 44 text

GraphQLに限りませんが、エラーレスポンスにスタックトレー スやライブラリのエラーメッセージなどを含まないようにしま しょう。