用GraphQL Ruby在响应头中回应查询的复杂度

简而言之

有时候,在执行 GraphQL 查询时,我们想要了解该查询的复杂程度。

我們試著將複雜度作為HTTP回應標頭的一種方式來解決這個問題。

我并不确定这个API设计有多常见,但是由于Contentful的GraphQL Content API中包含了在响应头中回复复杂度的设计,所以这并不是特别异常的事情。

The given phrase, “コード,” can be paraphrased in Chinese as “代碼” .

由于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中,从上下文中获取复杂度并设置到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

请提供更多详细信息让我更好地理解你的需求。

    https://graphql-ruby.org/queries/complexity_and_depth
广告
将在 10 秒后关闭
bannerAds