Skip to content

Commit c7b987d

Browse files
authored
feat: add support for the @interfaceObject directive (#218)
1 parent fc541ee commit c7b987d

File tree

4 files changed

+113
-32
lines changed

4 files changed

+113
-32
lines changed

lib/apollo-federation/object.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def inaccessible
2424
add_directive(name: 'inaccessible')
2525
end
2626

27+
def interface_object
28+
add_directive(name: 'interfaceObject')
29+
end
30+
2731
def key(fields:, camelize: true)
2832
add_directive(
2933
name: 'key',

lib/apollo-federation/schema.rb

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,11 @@ def self.included(klass)
1212
end
1313

1414
module CommonMethods
15-
FEDERATION_2_PREFIX = <<~SCHEMA
16-
extend schema
17-
@link(url: "https://specs.apollo.dev/federation/v2.0")
18-
19-
SCHEMA
15+
DEFAULT_LINK_NAMESPACE = 'federation'.freeze
2016

2117
def federation(version: '1.0', link: {})
2218
@federation_version = version
23-
@link = { as: 'federation' }.merge(link)
19+
@link = { as: DEFAULT_LINK_NAMESPACE }.merge(link)
2420
end
2521

2622
def federation_version
@@ -35,7 +31,7 @@ def federation_sdl(context: nil)
3531
document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context)
3632

3733
output = GraphQL::Language::Printer.new.print(document_from_schema.document)
38-
output.prepend(FEDERATION_2_PREFIX) if federation_2?
34+
output.prepend(federation_2_prefix) if federation_2?
3935
output
4036
end
4137

@@ -61,9 +57,11 @@ def query(new_query_object = nil)
6157
private
6258

6359
def federation_2_prefix
60+
federation_namespace = ", as: \"#{link_namespace}\"" if link_namespace != DEFAULT_LINK_NAMESPACE
61+
6462
<<~SCHEMA
6563
extend schema
66-
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "#{link_namespace}")
64+
@link(url: "https://specs.apollo.dev/federation/v2.3"#{federation_namespace})
6765
6866
SCHEMA
6967
end

spec/apollo-federation/schema_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222

2323
expect(schema.federation_version).to eq('2.0')
2424
end
25+
26+
it 'returns the specified version when set' do
27+
schema = Class.new(GraphQL::Schema) do
28+
include ApolloFederation::Schema
29+
federation version: '2.3'
30+
end
31+
32+
expect(schema.federation_version).to eq('2.3')
33+
end
2534
end
2635

2736
describe '.federation_2?' do
@@ -61,6 +70,15 @@
6170
expect(schema.federation_2?).to be(true)
6271
end
6372

73+
it 'returns true when the version is a float greater than 2.0' do
74+
schema = Class.new(GraphQL::Schema) do
75+
include ApolloFederation::Schema
76+
federation version: 2.3
77+
end
78+
79+
expect(schema.federation_2?).to be(true)
80+
end
81+
6482
it 'returns true when the version is a string greater than 2.0' do
6583
schema = Class.new(GraphQL::Schema) do
6684
include ApolloFederation::Schema
@@ -69,5 +87,14 @@
6987

7088
expect(schema.federation_2?).to be(true)
7189
end
90+
91+
it 'returns true when the version is a string greater than 2.0' do
92+
schema = Class.new(GraphQL::Schema) do
93+
include ApolloFederation::Schema
94+
federation version: '2.3'
95+
end
96+
97+
expect(schema.federation_2?).to be(true)
98+
end
7299
end
73100
end

spec/apollo-federation/service_field_v2_spec.rb

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def execute_sdl(schema)
109109
expect(execute_sdl(schema)).to match_sdl(
110110
<<~GRAPHQL,
111111
extend schema
112-
@link(url: "https://specs.apollo.dev/federation/v2.0")
112+
@link(url: "https://specs.apollo.dev/federation/v2.3")
113113
114114
type Product {
115115
upc: String!
@@ -144,7 +144,7 @@ def execute_sdl(schema)
144144
expect(execute_sdl(schema)).to match_sdl(
145145
<<~GRAPHQL,
146146
extend schema
147-
@link(url: "https://specs.apollo.dev/federation/v2.0")
147+
@link(url: "https://specs.apollo.dev/federation/v2.3")
148148
149149
type Product @federation__extends {
150150
upc: String!
@@ -180,7 +180,7 @@ def execute_sdl(schema)
180180
expect(execute_sdl(schema)).to match_sdl(
181181
<<~GRAPHQL,
182182
extend schema
183-
@link(url: "https://specs.apollo.dev/federation/v2.0")
183+
@link(url: "https://specs.apollo.dev/federation/v2.3")
184184
185185
type Position @federation__shareable {
186186
x: Int!
@@ -217,7 +217,7 @@ def execute_sdl(schema)
217217
expect(execute_sdl(schema)).to match_sdl(
218218
<<~GRAPHQL,
219219
extend schema
220-
@link(url: "https://specs.apollo.dev/federation/v2.0")
220+
@link(url: "https://specs.apollo.dev/federation/v2.3")
221221
222222
type Position @federation__inaccessible {
223223
x: Int!
@@ -254,7 +254,7 @@ def execute_sdl(schema)
254254
expect(execute_sdl(schema)).to match_sdl(
255255
<<~GRAPHQL,
256256
extend schema
257-
@link(url: "https://specs.apollo.dev/federation/v2.0")
257+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
258258
259259
type Product @fed2__extends {
260260
upc: String!
@@ -290,7 +290,7 @@ def execute_sdl(schema)
290290
expect(execute_sdl(schema)).to match_sdl(
291291
<<~GRAPHQL,
292292
extend schema
293-
@link(url: "https://specs.apollo.dev/federation/v2.0")
293+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
294294
295295
type Position @fed2__shareable {
296296
x: Int!
@@ -327,7 +327,7 @@ def execute_sdl(schema)
327327
expect(execute_sdl(schema)).to match_sdl(
328328
<<~GRAPHQL,
329329
extend schema
330-
@link(url: "https://specs.apollo.dev/federation/v2.0")
330+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
331331
332332
type Position @fed2__inaccessible {
333333
x: Int!
@@ -363,7 +363,7 @@ def execute_sdl(schema)
363363
expect(execute_sdl(schema)).to match_sdl(
364364
<<~GRAPHQL,
365365
extend schema
366-
@link(url: "https://specs.apollo.dev/federation/v2.0")
366+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
367367
368368
type Product @fed2__key(fields: "upc") {
369369
upc: String!
@@ -376,7 +376,7 @@ def execute_sdl(schema)
376376
)
377377
end
378378

379-
it 'returns valid SDL for @external directives' do
379+
it 'returns valid SDL for @external directives with custom namespace' do
380380
product = Class.new(base_object) do
381381
graphql_name 'Product'
382382
extend_type
@@ -394,7 +394,7 @@ def execute_sdl(schema)
394394
expect(execute_sdl(schema)).to match_sdl(
395395
<<~GRAPHQL,
396396
extend schema
397-
@link(url: "https://specs.apollo.dev/federation/v2.0")
397+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
398398
399399
type Product @fed2__extends @fed2__key(fields: "upc") {
400400
price: Int
@@ -403,6 +403,32 @@ def execute_sdl(schema)
403403
GRAPHQL
404404
)
405405
end
406+
407+
it 'returns valid SDL for @interfaceObject directives with custom namespace' do
408+
product = Class.new(base_object) do
409+
graphql_name 'Product'
410+
interface_object
411+
key fields: :id
412+
413+
field :id, 'ID', null: false
414+
end
415+
416+
schema = Class.new(base_schema) do
417+
orphan_types product
418+
federation version: '2.3', link: { as: 'fed2' }
419+
end
420+
421+
expect(execute_sdl(schema)).to match_sdl(
422+
<<~GRAPHQL,
423+
extend schema
424+
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
425+
426+
type Product @fed2__interfaceObject @fed2__key(fields: "id") {
427+
id: ID!
428+
}
429+
GRAPHQL
430+
)
431+
end
406432
end
407433

408434
it 'returns valid SDL for inaccessible interface types' do
@@ -444,7 +470,7 @@ def execute_sdl(schema)
444470
expect(execute_sdl(schema)).to match_sdl(
445471
<<~GRAPHQL,
446472
extend schema
447-
@link(url: "https://specs.apollo.dev/federation/v2.0")
473+
@link(url: "https://specs.apollo.dev/federation/v2.3")
448474
449475
type Book implements Product {
450476
upc: String!
@@ -507,7 +533,7 @@ def execute_sdl(schema)
507533
expect(execute_sdl(schema)).to match_sdl(
508534
<<~GRAPHQL,
509535
extend schema
510-
@link(url: "https://specs.apollo.dev/federation/v2.0")
536+
@link(url: "https://specs.apollo.dev/federation/v2.3")
511537
512538
type Book implements Product @federation__extends @federation__key(fields: "upc") {
513539
upc: String! @federation__external
@@ -547,7 +573,7 @@ def execute_sdl(schema)
547573
expect(execute_sdl(schema)).to match_sdl(
548574
<<~GRAPHQL,
549575
extend schema
550-
@link(url: "https://specs.apollo.dev/federation/v2.0")
576+
@link(url: "https://specs.apollo.dev/federation/v2.3")
551577
552578
type Product @federation__key(fields: "upc") {
553579
upc: String!
@@ -578,7 +604,7 @@ def execute_sdl(schema)
578604
expect(execute_sdl(schema)).to match_sdl(
579605
<<~GRAPHQL,
580606
extend schema
581-
@link(url: "https://specs.apollo.dev/federation/v2.0")
607+
@link(url: "https://specs.apollo.dev/federation/v2.3")
582608
583609
type Product @federation__key(fields: "upc") {
584610
upc: String!
@@ -606,7 +632,7 @@ def execute_sdl(schema)
606632
expect(execute_sdl(schema)).to match_sdl(
607633
<<~GRAPHQL,
608634
extend schema
609-
@link(url: "https://specs.apollo.dev/federation/v2.0")
635+
@link(url: "https://specs.apollo.dev/federation/v2.3")
610636
611637
type Product @federation__key(fields: "upc") @federation__key(fields: "name") {
612638
name: String
@@ -634,7 +660,7 @@ def execute_sdl(schema)
634660
expect(execute_sdl(schema)).to match_sdl(
635661
<<~GRAPHQL,
636662
extend schema
637-
@link(url: "https://specs.apollo.dev/federation/v2.0")
663+
@link(url: "https://specs.apollo.dev/federation/v2.3")
638664
639665
type Product @federation__extends @federation__key(fields: "upc") {
640666
price: Int
@@ -644,6 +670,32 @@ def execute_sdl(schema)
644670
)
645671
end
646672

673+
it 'returns valid SDL for @interfaceObject directives' do
674+
product = Class.new(base_object) do
675+
graphql_name 'Product'
676+
interface_object
677+
key fields: :id
678+
679+
field :id, 'ID', null: false
680+
end
681+
682+
schema = Class.new(base_schema) do
683+
orphan_types product
684+
federation version: '2.3'
685+
end
686+
687+
expect(execute_sdl(schema)).to match_sdl(
688+
<<~GRAPHQL,
689+
extend schema
690+
@link(url: "https://specs.apollo.dev/federation/v2.3")
691+
692+
type Product @federation__interfaceObject @federation__key(fields: "id") {
693+
id: ID!
694+
}
695+
GRAPHQL
696+
)
697+
end
698+
647699
it 'returns valid SDL for @shareable directives' do
648700
position = Class.new(base_object) do
649701
graphql_name 'Position'
@@ -666,7 +718,7 @@ def execute_sdl(schema)
666718
expect(execute_sdl(schema)).to match_sdl(
667719
<<~GRAPHQL,
668720
extend schema
669-
@link(url: "https://specs.apollo.dev/federation/v2.0")
721+
@link(url: "https://specs.apollo.dev/federation/v2.3")
670722
671723
type Position {
672724
x: Int! @federation__shareable
@@ -702,7 +754,7 @@ def execute_sdl(schema)
702754
expect(execute_sdl(schema)).to match_sdl(
703755
<<~GRAPHQL,
704756
extend schema
705-
@link(url: "https://specs.apollo.dev/federation/v2.0")
757+
@link(url: "https://specs.apollo.dev/federation/v2.3")
706758
707759
type Position {
708760
x: Int! @federation__inaccessible
@@ -734,7 +786,7 @@ def execute_sdl(schema)
734786
expect(execute_sdl(schema)).to match_sdl(
735787
<<~GRAPHQL,
736788
extend schema
737-
@link(url: "https://specs.apollo.dev/federation/v2.0")
789+
@link(url: "https://specs.apollo.dev/federation/v2.3")
738790
739791
type Product @federation__extends @federation__key(fields: "id") {
740792
id: ID!
@@ -770,7 +822,7 @@ def execute_sdl(schema)
770822
expect(execute_sdl(schema)).to match_sdl(
771823
<<~GRAPHQL,
772824
extend schema
773-
@link(url: "https://specs.apollo.dev/federation/v2.0")
825+
@link(url: "https://specs.apollo.dev/federation/v2.3")
774826
775827
type Product @federation__extends @federation__key(fields: "upc") {
776828
price: Int
@@ -805,7 +857,7 @@ def execute_sdl(schema)
805857
expect(execute_sdl(schema)).to match_sdl(
806858
<<~GRAPHQL,
807859
extend schema
808-
@link(url: "https://specs.apollo.dev/federation/v2.0")
860+
@link(url: "https://specs.apollo.dev/federation/v2.3")
809861
810862
type Product @federation__extends @federation__key(fields: "upc") {
811863
price: Int @federation__external
@@ -834,7 +886,7 @@ def execute_sdl(schema)
834886
expect(execute_sdl(schema)).to match_sdl(
835887
<<~GRAPHQL,
836888
extend schema
837-
@link(url: "https://specs.apollo.dev/federation/v2.0")
889+
@link(url: "https://specs.apollo.dev/federation/v2.3")
838890
839891
type Product @federation__key(fields: "productId") {
840892
productId: String!
@@ -862,7 +914,7 @@ def execute_sdl(schema)
862914
expect(execute_sdl(schema)).to match_sdl(
863915
<<~GRAPHQL,
864916
extend schema
865-
@link(url: "https://specs.apollo.dev/federation/v2.0")
917+
@link(url: "https://specs.apollo.dev/federation/v2.3")
866918
867919
type Product @federation__extends @federation__key(fields: "product_id") {
868920
options: [String!]! @federation__requires(fields: "my_id")
@@ -895,7 +947,7 @@ def self.visible?(context)
895947
expect(execute_sdl(schema)).to match_sdl(
896948
<<~GRAPHQL,
897949
extend schema
898-
@link(url: "https://specs.apollo.dev/federation/v2.0")
950+
@link(url: "https://specs.apollo.dev/federation/v2.3")
899951
900952
type Product @federation__extends @federation__key(fields: "upc") {
901953
upc: String! @federation__external

0 commit comments

Comments
 (0)