GraphQL-RubyのInstrumentationを翻訳して学んだこと

GraphQL-Rubyには、Queryの実行前後で処理を差し込むことが可能なInstrumentが実装されています。

この機能を利用するためには、必ず#before_query(query)#after_query(query)二つのメソッドを定義する必要があります。

以下のように自身のスキーマクラス内に追加します。

class MySchema < GraphQL::Schema
  instrument(:query, QueryTimerInstrumentation)
end

Railsアプリケーションの場合、ドキュメントに従うならばQueryTimerInstrumentationapp/graphql/query_timer_instrumentation.rbに定義するとよいでしょう。

module QueryTimerInstrumentation
  module_function

  # Log the time of the query
  def before_query(query)
    Rails.logger.info("Query begin: #{Time.now.to_i}")
  end

  def after_query(query)
    Rails.logger.info("Query end: #{Time.now.to_i}")
  end
end

各メソッドの引数である、queryはGraphQL::Queryクラスのインスタンスです。このことから上のログ機能を容易に拡張できます。

GraphQL::Queryは、lib/graphql/query.rbに定義されています。

利用できそうなメソッドとして、queryやmutation、subscriptionを判断できるquery?mutation?subscription?があります。

他にもprovided_variableoperation_namequery_stringメソッドなどを組み合わせることでGraphQL-RubyログGemなどが開発できそうです。

もう一点、補足しておくとquery、mutationともにGraphQL::Queryクラスであるためinstrument(:query, QueryTimerInstrumentation)を定義するだけでmutationに対してもhookされた状態となります。

気になる方は、query.class.ancestorsの実行結果がqueryとmutationで変化しないことを確かめてみるといいでしょう。

$ query.class.ancestors
=> [GraphQL::Query,
 GraphQL::Tracing::Traceable,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 Object,
 Tins::Full,
 FriendlyId::ObjectUtils,
 PP::ObjectMixin,
 JSON::Ext::Generator::GeneratorMethods::Object,
 ActiveSupport::Tryable,
 ActiveSupport::Dependencies::Loadable,
 Kernel,
 BasicObject]

初めてのGraphQL ―Webサービスを作って学ぶ新世代API

初めてのGraphQL ―Webサービスを作って学ぶ新世代API

  • 作者: Eve Porcello,Alex Banks,尾崎沙耶,あんどうやすし
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2019/11/13
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る