gqlgen で、オーバーフェッチを防ぐためのそのフィールド専用のリゾルバを定義する
1. gqlgen.yml で設定を有効化する
gqlgen.yml の autobind 設定のコメントを解除し、有効化する。
# gqlgen will search for any type names in the schema in these go packages # if they match it will use them, otherwise it will generate them. autobind: - "github.com/[username]/gqlgen-todos/graph/model"
この設定があることで、スキーマに定義されている型で、github.com/[username]/gqlgen-todos/graph/model
に対応するものがあればそれを利用し、定義されていなければ自動生成してくれるようになる。
2. gqlgen.yml に、リゾルバを利用するフィールドを明記する
gqlgen.yml の下部に記載。
# This section declares type mapping between the GraphQL and go type systems # # The first line in each type will be used as defaults for resolver arguments and # modelgen, the others will be allowed when binding to fields. Configure them to # your liking models: ID: model: - github.com/99designs/gqlgen/graphql.ID - github.com/99designs/gqlgen/graphql.Int - github.com/99designs/gqlgen/graphql.Int64 - github.com/99designs/gqlgen/graphql.Int32 Int: model: - github.com/99designs/gqlgen/graphql.Int - github.com/99designs/gqlgen/graphql.Int64 - github.com/99designs/gqlgen/graphql.Int32 Todo: # Todo型の fields: user: # user フィールドの resolver: true # リゾルバを有効化
3. model を定義する
graph/model/todo.go
にモデルを定義。
package model type Todo struct { ID string `json:"id"` Text string `json:"text"` Done bool `json:"done"` UserID string `json:"userId"` User *User `json:"user"` }
4. generate コマンド実行
go run github.com/99designs/gqlgen generate
5. Todo クラスの user フィールドを解決するリゾルバを実装
新たなリゾルバが生成されているため、中身を実装する。
func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, error) { return &model.User{ID: obj.UserID, Name: "user " + obj.UserID}, nil }
todoResolver
というのが、Todo クラスのフィールド用のリゾルバ。
これを実装することによって、Todo.user をクエリに指定された時に初めてユーザを取得する処理が走るようになる。
このように賢くオーバーフェッチを防げるのが、REST にはない、graphql の強みと言える。
(裏を返せば、うまくコントロールしてやらないと強みを活かせないとも言えるが).
最後に
この内容は gqlgen 公式のチュートリアルの内容と全く同じです。
あとで見返すときに英語の意味を考える手間を省くため。