Module: WCC::Contentful::Graphql::Federation
- Extended by:
- Federation
- Included in:
- Federation
- Defined in:
- lib/wcc/contentful/graphql/federation.rb,
lib/wcc/contentful/graphql/federation/builds_arguments.rb
Overview
Extend this module inside a root query definition to do schema federation. blog.apollographql.com/apollo-federation-f260cf525d21
This handles only queries, not mutations or subscriptions.
Defined Under Namespace
Classes: BuildsArguments, NamespacesTypes
Instance Method Summary collapse
- #delegate_to_schema(schema, field_name: nil, arguments: nil) ⇒ Object
-
#schema_stitch(schema, namespace: nil) ⇒ Object
Accepts an externally defined schema with a root query, and “stitches” it’s query root into the current GraphQL::ObjectType definition.
Instance Method Details
#delegate_to_schema(schema, field_name: nil, arguments: nil) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/wcc/contentful/graphql/federation.rb', line 51 def delegate_to_schema(schema, field_name: nil, arguments: nil) ->(obj, inner_args, context) { field_name ||= context.ast_node.name arguments = arguments.call(obj, inner_args, context) if arguments&.respond_to?(:call) arguments = BuildsArguments.call(arguments) if arguments arguments ||= context.ast_node.arguments field_node = GraphQL::Language::Nodes::Field.new( name: field_name, arguments: arguments, selections: context.ast_node.selections, directives: context.ast_node.directives ) query_node = GraphQL::Language::Nodes::OperationDefinition.new( name: context.query.operation_name, operation_type: 'query', variables: context.query.selected_operation.variables, selections: [ field_node ] ) # the ast_node.to_query_string prints the relevant section of the query to # a string. We build a query out of that which we execute on the external # schema. query = query_node.to_query_string result = schema.execute(query, variables: context.query.variables) if result['errors'].present? raise GraphQL::ExecutionError.new( result.dig('errors', 0, 'message'), ast_node: context.ast_node ) end result.dig('data', field_name) } end |
#schema_stitch(schema, namespace: nil) ⇒ Object
Accepts an externally defined schema with a root query, and “stitches” it’s query root into the current GraphQL::ObjectType definition. All fields on the external query object like ‘resource()`, `allResource()` will be inserted into the current object. The `resolve` method for those fields will execute a query on the external schema, returning the results.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/wcc/contentful/graphql/federation.rb', line 15 def schema_stitch(schema, namespace: nil) ns_titleized = namespace&.titleize ns = NamespacesTypes.new(namespace: ns_titleized) def_fields = proc { schema.query.fields.each do |(key, field_def)| field key, ns.namespaced(field_def.type) do description field_def.description field_def.arguments.each do |(arg_name, arg)| argument arg_name, ns.namespaced(arg.type) end resolve delegate_to_schema(schema) end end } if namespace stub_class = Struct.new(:name) namespaced_type = GraphQL::ObjectType.define do name ns_titleized instance_exec(&def_fields) end field namespace, namespaced_type do resolve ->(_obj, _arguments, _context) { stub_class.new(namespace) } end else def_fields.call end end |