LoginSignup
0
0

More than 1 year has passed since last update.

GraphQL Ruby でクエリの複雑度をレスポンスヘッダで応答する

Last updated at Posted at 2022-12-12

概要

GraphQLでクエリをしたときにそのクエリの複雑度がどの程度だったのかを把握したくなることがあります。

この問題を解決する手段として複雑度をHTTPレスポンスヘッダで応答できるようにしてみます。

このAPIデザインがどの程度一般的なのかはちゃんとわかっていないのですが、Contentful の GraphQL Content API にはレスポンスヘッダで複雑度を応答するデザインが含まれていましたので特別に異常なことではないでしょう。

コード

複雑度の計算をするアナライザとして GraphQL::Analysis::AST::QueryComplexity が標準で提供されていますので、これを継承してアナライザーを実装します。

OverseQueryComplexityComplexityAnalyzer をクラスを作り、#result メソッドをオーバーライドし 、ここではGraphQL::Analysis::AST::QueryComplexity#result で計算された複雑度を context に設定します。

また実装したアナライザーを有効にするために query_analyzer を使って宣言します。

class ObserveQueryComplexityAnalyzer < GraphQL::Analysis::AST::QueryComplexity
  def result
    complexity = super

    context = query.context if query

    context[:query_complexity] = complexity if context

    complexity
  end
end

class MySchema < GraphQL::Schema
  query_analyzer(ObserveQueryComplexityAnalyzer)
end

GraphqlController#execute では context から 複雑度を取り出し response.headers に設定します。

class GraphqlController < ApplicationController
  X_GRAPHQL_QUERY_COMPLEXITY = 'X-GraphQL-Query-Complexity'.freeze

  def execute
    result = MySchema.execute(params[:query],
                              variables:      ensure_hash(params[:variables]),
                              context:        context,
                              operation_name: params[:operationName])

    query_complexity = context[:query_complexity]

    response.headers[X_GRAPHQL_QUERY_COMPLEXITY] = query_complexity if query_complexity

    render json: result
  end

  private

  def context
    @context ||= {}
  end
end

cURL などでクエリして複雑度が応答されるか確認しましょう。

$ curl -vvv -H'Content-type: application/json' \
       -d'{ "query": "query { viewer { id name } }" }' \
       -XPOST $GRAPHQL_ENDPOINT 2>&1 | \
  grep x-graphql-query-complexity
< x-graphql-query-complexity: 3

参考

0
0
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
0
0