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

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

Overview

Module designed to be extended onto an SchemaDefinition::API instance to customize the schema artifacts based on the [Apollo Federation subgraph spec](www.apollographql.com/docs/federation/subgraph-spec/).

To use this module, pass it in ‘schema_definition_extension_modules` when defining your Local::RakeTasks.

Examples:

Define local rake tasks with this extension module

require "elastic_graph/apollo/schema_definition/api_extension"

ElasticGraph::Local::RakeTasks.new(
  local_config_yaml: "config/settings/local.yaml",
  path_to_schema: "config/schema.rb"
) do |tasks|
  tasks.schema_definition_extension_modules = [ElasticGraph::Apollo::SchemaDefinition::APIExtension]
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(api) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 106

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.
    # We also need to customize it.
    if type.name == "Query"
      customize_root_query_type(_ = type)
    elsif type.respond_to?(:apollo_shareable)
      (_ = type).apollo_shareable
    end
  end

  api.state.after_user_definition_complete do
    api.send(:define_apollo_schema_elements)
  end
end

Instance Method Details

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

This method returns an undefined value.

Applies an apollo tag to built-in types so that they are included in the Apollo contract schema.

Examples:

Tag all built-in types (except two) for inclusion in the ‘public` schema

ElasticGraph.define_schema do |schema|
  schema.tag_built_in_types_with "public", except: ["IntAggregatedValue", "FloatAggregatedValues"]
end

Parameters:

  • name (String)

    tag name

  • except (Array<String>) (defaults to: [])

    built-in types not to tag

See Also:



73
74
75
76
77
78
79
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 73

def tag_built_in_types_with(name, except: [])
  except_set = except.to_set
  on_built_in_types do |type|
    apollo_type = (_ = type) # : ApolloDirectives::Tag
    apollo_type.apollo_tag(name: name) unless except_set.include?(type.name)
  end
end

#target_apollo_federation_version(version) ⇒ void

This method returns an undefined value.

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 on an older version of Apollo federation.

Examples:

Set the Apollo Federation Version

ElasticGraph.define_schema do |schema|
  schema.target_apollo_federation_version "2.6"
end

Parameters:

  • version (String)

    version number



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/elastic_graph/apollo/schema_definition/api_extension.rb', line 92

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 Errors::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