lib/graphql/stitching/executor.rb in graphql-stitching-0.2.1 vs lib/graphql/stitching/executor.rb in graphql-stitching-0.2.2

- old
+ new

@@ -13,11 +13,11 @@ end def fetch(ops) op = ops.first # There should only ever be one per location at a time - query_document = build_query(op) + query_document = build_document(op, @executor.request.operation_name) query_variables = @executor.request.variables.slice(*op["variables"].keys) result = @executor.supergraph.execute_at_location(op["location"], query_document, query_variables, @executor.request.context) @executor.query_count += 1 @executor.data.merge!(result["data"]) if result["data"] @@ -27,17 +27,27 @@ end ops.map { op["key"] } end - def build_query(op) + # Builds root source documents + # "query MyOperation_1($var:VarType) { rootSelections ... }" + def build_document(op, operation_name = nil) + doc = String.new + doc << op["operation_type"] + + if operation_name + doc << " " << operation_name << "_" << op["key"].to_s + end + if op["variables"].any? variable_defs = op["variables"].map { |k, v| "$#{k}:#{v}" }.join(",") - "#{op["operation_type"]}(#{variable_defs})#{op["selections"]}" - else - "#{op["operation_type"]}#{op["selections"]}" + doc << "(" << variable_defs << ")" end + + doc << op["selections"] + doc end end class BoundarySource < GraphQL::Dataloader::Source def initialize(executor, location) @@ -60,11 +70,11 @@ memo[op] = origin_set if origin_set.any? end if origin_sets_by_operation.any? - query_document, variable_names = build_query(origin_sets_by_operation) + query_document, variable_names = build_document(origin_sets_by_operation, @executor.request.operation_name) variables = @executor.request.variables.slice(*variable_names) raw_result = @executor.supergraph.execute_at_location(@location, query_document, variables, @executor.request.context) @executor.query_count += 1 merge_results!(origin_sets_by_operation, raw_result.dig("data")) @@ -74,11 +84,18 @@ end ops.map { origin_sets_by_operation[_1] ? _1["key"] : nil } end - def build_query(origin_sets_by_operation) + # Builds batched boundary queries + # "query MyOperation_2_3($var:VarType) { + # _0_result: list(keys:["a","b","c"]) { boundarySelections... } + # _1_0_result: item(key:"x") { boundarySelections... } + # _1_1_result: item(key:"y") { boundarySelections... } + # _1_2_result: item(key:"z") { boundarySelections... } + # }" + def build_document(origin_sets_by_operation, operation_name = nil) variable_defs = {} query_fields = origin_sets_by_operation.map.with_index do |(op, origin_set), batch_index| variable_defs.merge!(op["variables"]) boundary = op["boundary"] key_selection = "_STITCH_#{boundary["selection"]}" @@ -92,17 +109,27 @@ "_#{batch_index}_#{index}_result: #{boundary["field"]}(#{boundary["arg"]}:#{input}) #{op["selections"]}" end end end - query_document = if variable_defs.any? - query_variables = variable_defs.map { |k, v| "$#{k}:#{v}" }.join(",") - "query(#{query_variables}){ #{query_fields.join(" ")} }" - else - "query{ #{query_fields.join(" ")} }" + doc = String.new + doc << "query" # << boundary fulfillment always uses query + + if operation_name + doc << " " << operation_name + origin_sets_by_operation.each_key do |op| + doc << "_" << op["key"].to_s + end end - return query_document, variable_defs.keys + if variable_defs.any? + variable_str = variable_defs.map { |k, v| "$#{k}:#{v}" }.join(",") + doc << "(" << variable_str << ")" + end + + doc << "{ " << query_fields.join(" ") << " }" + + return doc, variable_defs.keys end def merge_results!(origin_sets_by_operation, raw_result) return unless raw_result