😀

【Golang✖️gqlgen】不要なDB取得を防ぐmodel reselverの実装

2022/07/29に公開

前提知識

  • 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