😀
【Golang✖️gqlgen】不要なDB取得を防ぐmodel reselverの実装
前提知識
- GraphQLの基本がわかる
- Golangの基本文法がわかる
- Gqlgenの基本がわかる
背景
gqlgenを使ってGraphqlを実装しました。その時にqueryを呼び出すときに不要なデータも取得してしまいます。これを解決するためにmodelresolver(ここではtodoresolver)を実装したいと思いました。
前提条件
DBにtodoとuserを作成し、外部キーで接続しています。queryreselverを用いてDBからtodoと外部キーで繋いだuserを取得するtodoメソッドを実装しました。
queryを実行
この時にtodoだけを取得したいときでも外部キーで接続しているuserのsqlも発行してしまいます。
todoreselverの実装
このように不要なデータをDBから取得してしまいます。これを解消するためにtodo reselverを使用してUserメソッドを実装します。
まず、下記ファイルの自動で生成されるtodoの型を削除します。
models_gen.go
package model
type NewTodo struct {
Title string `json:"title"`
UserID string `json:"userId"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
models/todo.goを作成し次のようにコードを追加します。
models/todo.go
package models
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
UserID int `json:"userID"`
}
gqlgen.ymlに以下のように追加します。
gqlgen.yml
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:
model: api/graph/models.Todo
ここで下記のコマンドを実行してください。
go run github.com/99designs/gqlgen
最後にschema.resolvers.goのTodoとUserメソッドを編集します。
schema.resolvers.go
func (r *queryResolver) Todo(ctx context.Context, id int) (*models.Todo, error) {
db := r.Resolver.DB
var todo models.Todo
err := db.First(&todo, id).Error
if err != nil {
return nil, err
}
return &todo, err
}
,
,
,
func (r *todoResolver) User(ctx context.Context, obj *models.Todo) (*model.User, error) {
db := r.Resolver.DB
var user model.User
err := db.First(&user, obj.UserID).Error
if err != nil {
return nil, err
}
return &user, err
}
これでもう一度queryを実行すると、結果は変わりませんがuserのsqlが発行されなくなりました。
Discussion