LoginSignup
19
6

More than 3 years have passed since last update.

gqlgenでresolver・model・schemaファイルを分割しコードの見通しを良くする

Last updated at Posted at 2021-03-19

gqlgenで開発していると、gqlgen generateで生成されるresolversとmodelsが長くなってしまい、分割したくなることがあると思いますので、その方法を書きます。

■方針
今回は、GraphQL形式でクライアントがDBのデータをリクエストすることを可能にするGraphQLサーバをGoで構築することが目的だったことから、schema、resolvers、modelsをテーブル単位で分割することにしました。

model分割

ここはドキュメント読めば分かると思うのですが一応書きます。
↓分割する際にはmodels_gen.goにある構造体をテーブル毎にファイル分割して、あとは↓のようにgqlgen.ymlに書いておけばgo generate ./...で新しく生成されなくなります。


models:
  Users:
    model: git-xxx/repository-name/graph/model.Users

resolvers・schemaファイル分割

一番分割したかったのがresolversファイル。ドキュメントを読んでも分割する方法が書いてなかったのですが、issueを読んだらやり方が書いてあったので試してみたらできました。自動生成されるやつは中身ブラックボックスになりがちで、良く分からないけど言われた通りにやってみたらできたみたいな腑に落ちなさが残る。
↓resolves.goが長くなって困っている人がissueを上げていました。

手順

  1. schemaを定義する*.graphqlsをテーブル毎に分割する
  2. type, input, Query, Mutationなど全てテーブル単位で分割したファイルに移動する
  3. Query, Mutationにextendをつける↓
graph/schema/user.graphql

extend type Query {
    UserByID(id: ID!): User
}

extend type Mutation {
    CreateUser(input: CreateUser!): User!
}

gqlgen.ymlで関係する部分はこのようになっています。

gqlgen.yml
# Where should the resolver implementations go?
resolver:
  layout: follow-schema
  dir: graph/resolver
  package: resolver
  filename_template: "{name}.resolvers.go"

これでgo generate ./...してあげるとテーブル毎のresolverが生成されるはずです。

あとは元々存在していたresolvers.goは削除してあげれば完了です。ドキュメントにextendなんて書いてあったかな・・・?

分からないのは、↓達がある特定のファイルに決まって生成されるのだけど、それがどのように決まるのかが謎。一番上にあるから?
気持ち的にはテーブルに対応していない別のファイルに移したいのだが、gqlgen generateする度に同じファイルに生成されるため、良く分からないけど気持ち悪さがあるだけで特に支障はないので一旦放置。

table1.go
...//table1関連の実装

// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }

// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }

type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }

追記

mutationResolver, queryResolverが自動的にgqlgenによってその時のschema定義によって決まったファイルに生成されてしまい、自分で好きなところに置いた後に自動生成されるのを防ぐ方法が分かっていなかったがissueを読んでいたら方法を発見したので追記。
やり方は簡単で、yamlファイルのresolverセクションを削除すればOK。自動生成されなくなるというデメリットはあるけれど、自分でやるのも簡単なのでコードの見通しが良くなるという利点の方が大きいので消してしまって問題ないと思う。

↓はissueで丁寧に回答に答えてくれていた聖人のコメント。

# Where should the resolver implementations go?
resolver:
  layout: follow-schema
  dir: graph/resolver
  package: resolver

@bofia thank you, unfortunately there is zero documentation on the yaml file, and I've been using gqlgen for much longer than most of these features existed.
You will want to remove the resolver section of the yaml file. This autogenerates the resolver in an opinionated way which, as you've noticed, doesn't scale well. Great for a new small project, but not good for what you are trying to do.
You can then create the resolvers yourself (which is really simple and easy), as well as customize them and avoid the auto-generate making a mess of your code

所感

これで他のソースコード部分と同様に、きれいにテーブル単位でファイルを分割できたので良かった。
思ったのはドキュメントの情報量が少なくて、ちゃんとissueの方も読まないといけないんだなということ。それがOSSというものなんでしょうか。

おしまい

19
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
6