RailsでGraphQLをつかうためには次のgemを使うことになると思う。
https://github.com/rmosolgo/graphql-ruby
GraphQLを利用すると、容易にN+1が発生する。
そこで次のようなコードを考えた。
module ShopsResolver
def self.call(obj, args, ctx)
limit = args[:limit]
order = args[:order]
bookable = args[:bookable]
shops = Shop.visible
shops = shops.limit(limit) if limit.present?
shops = shops.order('RAND()') if order == "TRENDING" # 仮実装
shops = shops.order('RAND()') if order == "RANKING" # 仮実装
shops = shops.where(bookable: bookable) if bookable.present?
shops = shops.includes(:area)
shops = shops.includes(:categories)
shops = shops.includes(:shop_categories)
shops = shops.includes(:category_subs)
shops = shops.includes(:shop_category_subs)
shops = shops.includes(:situations)
shops
end
end
むやみにincludesをつけまくると、余計なSQL発行が発生して良くない。
そこで、対策を検索した。
- Q: Prevent N+1 queries · Issue #189 · rmosolgo/graphql-ruby
- Pre-loading/Eager loading nested associations · Issue #58 · rmosolgo/graphql-ruby
とりあえずincludesを全部消して https://github.com/salsify/goldiloader を入れて対応した。
goldiloaderを使ってみたところ、GraphQLではうまく動いたが、一部システムが動かなくなった。
影響範囲が大きかったため https://github.com/Shopify/graphql-batch を試すことにした(続く)