Module: ElasticGraph::Apollo::SchemaDefinition::APIExtension

Defined in:
lib/elastic_graph/apollo/schema_definition/api_extension.rb

Overview

Module designed to be extended onto an ‘ElasticGraph::SchemaDefinition::API` instance to customize the schema artifacts based on the Apollo Federation subgraph spec:

www.apollographql.com/docs/federation/subgraph-spec/

Note that at this time we do not yet support extending a type owned by another subgraph (which the ‘@requires`, `@provides`, `@extends`, and `@external` directives are used for).

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(api) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 61

def self.extended(api)
  api.factory.extend FactoryExtension
  api.state.extend StateExtension

  latest_federation_version = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION
    .keys
    .max_by { |v| v.split(".").map(&:to_i) } # : ::String

  api.target_apollo_federation_version latest_federation_version

  api.on_built_in_types do |type|
    # Built-in types like `PageInfo` need to be tagged with `@shareable` on Federation V2 since other subgraphs may
    # have them and they aren't entity types. `Query`, as the root, is a special case that must be skipped.
    (_ = type).apollo_shareable if type.respond_to?(:apollo_shareable) && type.name != "Query"
  end
end

Instance Method Details

#resultsObject



28
29
30
31
32
33
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 28

def results
  register_graphql_extension GraphQL::EngineExtension, defined_at: "elastic_graph/apollo/graphql/engine_extension"
  define_apollo_schema_elements

  super
end

#tag_built_in_types_with(name, except: []) ⇒ Object

Called from the public API, as:

schema.tag_built_in_types_with "tag-name", except: ["IntAggregatedValues", ...]


37
38
39
40
41
42
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 37

def tag_built_in_types_with(name, except: [])
  except_set = except.to_set
  on_built_in_types do |type|
    type.directive("tag", name: name) unless except_set.include?(type.name)
  end
end

#target_apollo_federation_version(version) ⇒ Object

Picks which version of Apollo federation to target. By default, the latest supported version is targeted, but you can call this to pick an earlier version, which may be necessary if your organization is running an old version of Apollo studio.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 47

def target_apollo_federation_version(version)
  # Allow the version to have the `v` prefix, but don't require it.
  version = version.delete_prefix("v")

  state.apollo_directive_definitions = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION.fetch(version) do
    supported_version_descriptions = DIRECTIVE_DEFINITIONS_BY_FEDERATION_VERSION.keys.map do |version_number|
      "v#{version_number}"
    end.join(", ")

    raise SchemaError, "elasticgraph-apollo v#{ElasticGraph::VERSION} does not support Apollo federation v#{version}. " \
      "Pick one of the supported versions (#{supported_version_descriptions}) instead."
  end
end