From c8f525933550ce272250744fa51fcba1c854d4fa Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Wed, 14 Jun 2023 20:00:57 +0200 Subject: [PATCH 1/7] Add support for @composeDirective --- ...derated_document_from_schema_definition.rb | 2 +- lib/apollo-federation/schema.rb | 56 +++++++++++--- .../service_field_v2_spec.rb | 75 ++++++++++++++++--- 3 files changed, 112 insertions(+), 21 deletions(-) diff --git a/lib/apollo-federation/federated_document_from_schema_definition.rb b/lib/apollo-federation/federated_document_from_schema_definition.rb index 8d2f13d7d..cb58fabeb 100644 --- a/lib/apollo-federation/federated_document_from_schema_definition.rb +++ b/lib/apollo-federation/federated_document_from_schema_definition.rb @@ -101,7 +101,7 @@ def merge_directives(node, type) def directive_name(directive) if schema.federation_2? && !Schema::IMPORTED_DIRECTIVES.include?(directive[:name]) - "#{schema.link_namespace}__#{directive[:name]}" + "#{schema.default_link_namespace}__#{directive[:name]}" else directive[:name] end diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index ba7e6d24e..917ced53a 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -8,6 +8,7 @@ module ApolloFederation module Schema IMPORTED_DIRECTIVES = ['inaccessible', 'tag'].freeze + IMPORTED_DIRECTIVES_V2_1 = ['composeDirective'].freeze def self.included(klass) klass.extend(CommonMethods) @@ -16,9 +17,16 @@ def self.included(klass) module CommonMethods DEFAULT_LINK_NAMESPACE = 'federation' - def federation(version: '1.0', link: {}) + def federation(version: '1.0', default_link_namespace: nil, links: [], compose_directives: []) @federation_version = version - @link = { as: DEFAULT_LINK_NAMESPACE }.merge(link) + @default_link_namespace = default_link_namespace + @links = links + + if !federation_2_1? && compose_directives.any? + raise ArgumentError, 'composeDirective is available in Federation 2.1 and later' + end + + @compose_directives = compose_directives end def federation_version @@ -29,6 +37,10 @@ def federation_2? Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.0.0') end + def federation_2_1? + Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.1.0') + end + def federation_sdl(context: nil) document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context) @@ -37,8 +49,8 @@ def federation_sdl(context: nil) output end - def link_namespace - @link ? @link[:as] : find_inherited_value(:link_namespace) + def default_link_namespace + @default_link_namespace || find_inherited_value(:default_link_namespace, DEFAULT_LINK_NAMESPACE) end def query(new_query_object = nil) @@ -62,14 +74,40 @@ def original_query @orig_query_object || find_inherited_value(:original_query) end + def compose_directives + @compose_directives || find_inherited_value(:compose_directives, []) + end + + def links + @links || find_inherited_value(:links, []) + end + + def all_links + imported_directives = IMPORTED_DIRECTIVES + imported_directives += IMPORTED_DIRECTIVES_V2_1 if federation_2_1? + default_link = { + url: 'https://specs.apollo.dev/federation/v2.3', + import: imported_directives, + } + default_link[:as] = default_link_namespace if default_link_namespace != DEFAULT_LINK_NAMESPACE + [default_link, *links] + end + def federation_2_prefix - federation_namespace = ", as: \"#{link_namespace}\"" if link_namespace != DEFAULT_LINK_NAMESPACE + schema = "extend schema\n" - <<~SCHEMA - extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3"#{federation_namespace}, import: [#{(IMPORTED_DIRECTIVES.map { |directive| "\"@#{directive}\"" }).join(', ')}]) + all_links.each do |link| + schema += " @link(url: \"#{link[:url]}\"" + schema += ", as: \"#{link[:as]}\"" if link[:as] + schema += ", import: [#{link[:import].map { |d| "\"@#{d}\"" }.join(', ')}]" if link[:import] + schema += ")\n" + end + + compose_directives.each do |directive| + schema += " @composeDirective(name: \"@#{directive}\")\n" + end - SCHEMA + schema + "\n" end def schema_entities diff --git a/spec/apollo-federation/service_field_v2_spec.rb b/spec/apollo-federation/service_field_v2_spec.rb index bb7fd83f1..6c4963fb0 100644 --- a/spec/apollo-federation/service_field_v2_spec.rb +++ b/spec/apollo-federation/service_field_v2_spec.rb @@ -128,6 +128,59 @@ def execute_sdl(schema) ) end + it 'returns the federation SDL with compose directives for the schema' do + complexity_directive = Class.new(GraphQL::Schema::Directive) do + graphql_name 'complexity' + argument :fixed, Integer + description 'complexity of the field' + locations GraphQL::Schema::Directive::FIELD_DEFINITION + end + + product = Class.new(base_object) do + graphql_name 'Product' + + field :upc, String, null: false + end + + query_obj = Class.new(base_object) do + graphql_name 'Query' + + field :product, product, null: true, directives: { complexity_directive => { fixed: 1 } } + end + + schema = Class.new(base_schema) do + query query_obj + federation version: '2.3', + links: [{ + url: 'https://specs.example.com/federation/v2.3', + import: [complexity_directive.graphql_name], + }], + compose_directives: [complexity_directive.graphql_name] + end + + expect(execute_sdl(schema)).to match_sdl( + <<~GRAPHQL, + extend schema + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) + @link(url: "https://specs.example.com/federation/v2.3", import: ["@complexity"]) + @composeDirective(name: "@complexity") + + """ + complexity of the field + """ + directive @complexity(fixed: Int!) on FIELD_DEFINITION + + type Product { + upc: String! + } + + type Query { + product: Product @complexity(fixed: 1) + } + GRAPHQL + ) + end + it 'returns valid SDL for type extensions' do product = Class.new(base_object) do graphql_name 'Product' @@ -291,7 +344,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do query query_obj - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -327,7 +380,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do query query_obj - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -364,7 +417,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do query query_obj - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -401,7 +454,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do query query_obj - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -437,7 +490,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do query query_obj - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -468,7 +521,7 @@ def execute_sdl(schema) schema = Class.new(base_schema) do orphan_types product - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( @@ -495,13 +548,13 @@ def execute_sdl(schema) schema = Class.new(base_schema) do orphan_types product - federation version: '2.3', link: { as: 'fed2' } + federation version: '2.3', default_link_namespace: 'fed2' end expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__interfaceObject @fed2__key(fields: "id") { id: ID! @@ -1421,7 +1474,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__interfaceObject @federation__key(fields: "id") { id: ID! @@ -1973,7 +2026,7 @@ def self.visible?(context) end new_base_schema = Class.new(base_schema) do - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' end schema = Class.new(new_base_schema) do @@ -2011,7 +2064,7 @@ def self.visible?(context) end new_base_schema = Class.new(base_schema) do - federation version: '2.0', link: { as: 'fed2' } + federation version: '2.0', default_link_namespace: 'fed2' query query_obj end From 2f19d5e5cc707cd77f87afa1e42e026bc0f0cdc2 Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Thu, 15 Jun 2023 10:01:22 +0200 Subject: [PATCH 2/7] Use schema.join --- lib/apollo-federation/schema.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index 917ced53a..73f718de6 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -94,20 +94,24 @@ def all_links end def federation_2_prefix - schema = "extend schema\n" + schema = ["extend schema"] all_links.each do |link| - schema += " @link(url: \"#{link[:url]}\"" - schema += ", as: \"#{link[:as]}\"" if link[:as] - schema += ", import: [#{link[:import].map { |d| "\"@#{d}\"" }.join(', ')}]" if link[:import] - schema += ")\n" + link_str = " @link(url: \"#{link[:url]}\"" + link_str += ", as: \"#{link[:as]}\"" if link[:as] + link_str += ", import: [#{link[:import].map { |d| "\"@#{d}\"" }.join(', ')}]" if link[:import] + link_str += ")" + schema << link_str end compose_directives.each do |directive| - schema += " @composeDirective(name: \"@#{directive}\")\n" + schema << " @composeDirective(name: \"@#{directive}\")" end - schema + "\n" + schema << '' + schema << '' + + schema.join("\n") end def schema_entities From 66d060d60c70bc40bf2a17f55df467095992110d Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Fri, 16 Jun 2023 10:30:44 +0200 Subject: [PATCH 3/7] Lint, add links test --- lib/apollo-federation/schema.rb | 4 +- .../service_field_v2_spec.rb | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index 73f718de6..893db3809 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -94,13 +94,13 @@ def all_links end def federation_2_prefix - schema = ["extend schema"] + schema = ['extend schema'] all_links.each do |link| link_str = " @link(url: \"#{link[:url]}\"" link_str += ", as: \"#{link[:as]}\"" if link[:as] link_str += ", import: [#{link[:import].map { |d| "\"@#{d}\"" }.join(', ')}]" if link[:import] - link_str += ")" + link_str += ')' schema << link_str end diff --git a/spec/apollo-federation/service_field_v2_spec.rb b/spec/apollo-federation/service_field_v2_spec.rb index 6c4963fb0..4c0ff67ca 100644 --- a/spec/apollo-federation/service_field_v2_spec.rb +++ b/spec/apollo-federation/service_field_v2_spec.rb @@ -128,6 +128,45 @@ def execute_sdl(schema) ) end + it 'returns the federation SDL with multiple links for the schema' do + product = Class.new(base_object) do + graphql_name 'Product' + + field :upc, String, null: false + end + + query_obj = Class.new(base_object) do + graphql_name 'Query' + + field :product, product, null: true + end + + schema = Class.new(base_schema) do + query query_obj + federation version: '2.3', + links: [{ + url: 'https://specs.example.com/federation/v2.3', + import: ['test'], + }] + end + + expect(execute_sdl(schema)).to match_sdl( + <<~GRAPHQL, + extend schema + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) + @link(url: "https://specs.example.com/federation/v2.3", import: ["@test"]) + + type Product { + upc: String! + } + + type Query { + product: Product + } + GRAPHQL + ) + end + it 'returns the federation SDL with compose directives for the schema' do complexity_directive = Class.new(GraphQL::Schema::Directive) do graphql_name 'complexity' From ede329be00ad5d1a3db1db40c87eed1e6e6efd80 Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Fri, 16 Jun 2023 10:43:01 +0200 Subject: [PATCH 4/7] Add required to argument --- spec/apollo-federation/service_field_v2_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/apollo-federation/service_field_v2_spec.rb b/spec/apollo-federation/service_field_v2_spec.rb index 4c0ff67ca..3ba30f0a2 100644 --- a/spec/apollo-federation/service_field_v2_spec.rb +++ b/spec/apollo-federation/service_field_v2_spec.rb @@ -170,7 +170,7 @@ def execute_sdl(schema) it 'returns the federation SDL with compose directives for the schema' do complexity_directive = Class.new(GraphQL::Schema::Directive) do graphql_name 'complexity' - argument :fixed, Integer + argument :fixed, Integer, required: true description 'complexity of the field' locations GraphQL::Schema::Directive::FIELD_DEFINITION end From 96ec2ca64f96f60d0ce0372b9cd0a206fad377b5 Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Tue, 1 Aug 2023 11:51:56 +0200 Subject: [PATCH 5/7] Drop minor version check --- lib/apollo-federation/schema.rb | 13 +-- .../service_field_v2_spec.rb | 96 +++++++++---------- 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index 893db3809..5827684f3 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -7,8 +7,7 @@ module ApolloFederation module Schema - IMPORTED_DIRECTIVES = ['inaccessible', 'tag'].freeze - IMPORTED_DIRECTIVES_V2_1 = ['composeDirective'].freeze + IMPORTED_DIRECTIVES = ['inaccessible', 'tag', 'composeDirective'].freeze def self.included(klass) klass.extend(CommonMethods) @@ -21,11 +20,6 @@ def federation(version: '1.0', default_link_namespace: nil, links: [], compose_d @federation_version = version @default_link_namespace = default_link_namespace @links = links - - if !federation_2_1? && compose_directives.any? - raise ArgumentError, 'composeDirective is available in Federation 2.1 and later' - end - @compose_directives = compose_directives end @@ -37,10 +31,6 @@ def federation_2? Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.0.0') end - def federation_2_1? - Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.1.0') - end - def federation_sdl(context: nil) document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context) @@ -84,7 +74,6 @@ def links def all_links imported_directives = IMPORTED_DIRECTIVES - imported_directives += IMPORTED_DIRECTIVES_V2_1 if federation_2_1? default_link = { url: 'https://specs.apollo.dev/federation/v2.3', import: imported_directives, diff --git a/spec/apollo-federation/service_field_v2_spec.rb b/spec/apollo-federation/service_field_v2_spec.rb index 3ba30f0a2..fa3112e90 100644 --- a/spec/apollo-federation/service_field_v2_spec.rb +++ b/spec/apollo-federation/service_field_v2_spec.rb @@ -115,7 +115,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { upc: String! @@ -242,7 +242,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends { upc: String! @@ -278,7 +278,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @federation__shareable { x: Int! @@ -315,7 +315,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @inaccessible { x: Int! @@ -352,7 +352,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @tag(name: "private") { x: Int! @@ -389,7 +389,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__extends { upc: String! @@ -425,7 +425,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @fed2__shareable { x: Int! @@ -462,7 +462,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @inaccessible { x: Int! @@ -499,7 +499,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position @tag(name: "private") { x: Int! @@ -535,7 +535,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__key(fields: "upc") { upc: String! @@ -566,7 +566,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__extends @fed2__key(fields: "upc") { price: Int @@ -642,7 +642,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Book implements Product { upc: String! @@ -694,7 +694,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Book implements Product { upc: String! @@ -757,7 +757,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Book implements Product @federation__extends @federation__key(fields: "upc") { upc: String! @federation__external @@ -801,7 +801,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Book { upc: String! @@ -839,7 +839,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Book { upc: String! @@ -877,7 +877,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) enum ProductType @tag(name: "private") { BOOK @@ -914,7 +914,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) enum ProductType @inaccessible { BOOK @@ -955,7 +955,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { upc: UPC! @@ -1001,7 +1001,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { upc: UPC! @@ -1051,7 +1051,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1106,7 +1106,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1161,7 +1161,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1216,7 +1216,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1265,7 +1265,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1310,7 +1310,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) """ Autogenerated return type of CreateProduct. @@ -1349,7 +1349,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "upc") { upc: String! @@ -1380,7 +1380,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "upc") { upc: String! @@ -1408,7 +1408,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "upc") @federation__key(fields: "name") { name: String @@ -1434,7 +1434,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "upc", resolvable: false) { upc: String! @@ -1459,7 +1459,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "upc") { upc: String! @@ -1486,7 +1486,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "upc") { price: Int @@ -1544,7 +1544,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position { x: Int! @federation__shareable @@ -1580,7 +1580,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position { x: Int! @inaccessible @@ -1616,7 +1616,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position { x: Int! @tag(name: "private") @@ -1652,7 +1652,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Position { x: Int! @tag(name: "private") @tag(name: "protected") @@ -1704,7 +1704,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { type: ProductType! @@ -1760,7 +1760,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { type: ProductType! @@ -1816,7 +1816,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product { type: ProductType! @@ -1852,7 +1852,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "id") { id: ID! @@ -1888,7 +1888,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "upc") { price: Int @@ -1923,7 +1923,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "upc") { price: Int @federation__external @@ -1952,7 +1952,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "productId") { productId: String! @@ -1980,7 +1980,7 @@ def execute_sdl(schema) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "product_id") { options: [String!]! @federation__requires(fields: "my_id") @@ -2013,7 +2013,7 @@ def self.visible?(context) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__extends @federation__key(fields: "upc") { upc: String! @federation__external @@ -2041,7 +2041,7 @@ def self.visible?(context) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @federation__key(fields: "id") { id: ID! @@ -2075,7 +2075,7 @@ def self.visible?(context) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__extends { upc: String! @@ -2112,7 +2112,7 @@ def self.visible?(context) expect(execute_sdl(schema)).to match_sdl( <<~GRAPHQL, extend schema - @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag"]) + @link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2", import: ["@inaccessible", "@tag", "@composeDirective"]) type Product @fed2__extends { upc: String! From d373b7aee41df02653fb1e7779187b21565f5b60 Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Tue, 1 Aug 2023 12:07:16 +0200 Subject: [PATCH 6/7] Make federation_2_prefix easier to read --- lib/apollo-federation/schema.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index 5827684f3..658479125 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -86,9 +86,13 @@ def federation_2_prefix schema = ['extend schema'] all_links.each do |link| - link_str = " @link(url: \"#{link[:url]}\"" + link_str = " @link(" + link_str += "url: \"#{link[:url]}\"" link_str += ", as: \"#{link[:as]}\"" if link[:as] - link_str += ", import: [#{link[:import].map { |d| "\"@#{d}\"" }.join(', ')}]" if link[:import] + if link[:import] + imported_directives = link[:import].map { |d| "\"@#{d}\"" }.join(', ') + link_str += ", import: [#{imported_directives}]" + end link_str += ')' schema << link_str end From 0701bff63e50cf91e57f0eef528b2c0d31bd6127 Mon Sep 17 00:00:00 2001 From: Yannick Utard Date: Tue, 1 Aug 2023 12:12:56 +0200 Subject: [PATCH 7/7] Lint --- lib/apollo-federation/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/apollo-federation/schema.rb b/lib/apollo-federation/schema.rb index 658479125..e06a79d43 100644 --- a/lib/apollo-federation/schema.rb +++ b/lib/apollo-federation/schema.rb @@ -86,7 +86,7 @@ def federation_2_prefix schema = ['extend schema'] all_links.each do |link| - link_str = " @link(" + link_str = ' @link(' link_str += "url: \"#{link[:url]}\"" link_str += ", as: \"#{link[:as]}\"" if link[:as] if link[:import]