用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