Skip to content

Commit

Permalink
feat: add support for the @interfaceObject directive
Browse files Browse the repository at this point in the history
  • Loading branch information
moonflare committed Jan 31, 2023
1 parent fc541ee commit b141d87
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 17 deletions.
4 changes: 4 additions & 0 deletions lib/apollo-federation/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def inaccessible
add_directive(name: 'inaccessible')
end

def interface_object
add_directive(name: 'interfaceObject')
end

def key(fields:, camelize: true)
add_directive(
name: 'key',
Expand Down
21 changes: 10 additions & 11 deletions lib/apollo-federation/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,27 @@ def self.included(klass)
end

module CommonMethods
FEDERATION_2_PREFIX = <<~SCHEMA
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
SCHEMA
DEFAULT_LINK_NAMESPACE = 'federation'.freeze
SUPPORTED_FED2_VERSIONS = ['2.0', '2.1', '2.2', '2.3'].freeze

def federation(version: '1.0', link: {})
@federation_version = version
@link = { as: 'federation' }.merge(link)
@federation_version = version.to_f.to_s
@link = { as: DEFAULT_LINK_NAMESPACE }.merge(link)
end

def federation_version
@federation_version || '1.0'
@spec_version = SUPPORTED_FED2_VERSIONS.find {|version| @federation_version&.start_with?(version) } || '1.0'
end

def federation_2?
Gem::Version.new(federation_version.to_s) >= Gem::Version.new('2.0.0')
Gem::Version.new(federation_version) >= Gem::Version.new('2.0.0')
end

def federation_sdl(context: nil)
document_from_schema = FederatedDocumentFromSchemaDefinition.new(self, context: context)

output = GraphQL::Language::Printer.new.print(document_from_schema.document)
output.prepend(FEDERATION_2_PREFIX) if federation_2?
output.prepend(federation_2_prefix) if federation_2?
output
end

Expand All @@ -61,9 +58,11 @@ def query(new_query_object = nil)
private

def federation_2_prefix
federation_namespace = ", as: \"#{link_namespace}\"" if link_namespace != DEFAULT_LINK_NAMESPACE

<<~SCHEMA
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "#{link_namespace}")
@link(url: "https://specs.apollo.dev/federation/v#{federation_version}"#{federation_namespace})
SCHEMA
end
Expand Down
27 changes: 27 additions & 0 deletions spec/apollo-federation/schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@

expect(schema.federation_version).to eq('2.0')
end

it 'returns the specified version when set' do
schema = Class.new(GraphQL::Schema) do
include ApolloFederation::Schema
federation version: '2.3'
end

expect(schema.federation_version).to eq('2.3')
end
end

describe '.federation_2?' do
Expand Down Expand Up @@ -61,6 +70,15 @@
expect(schema.federation_2?).to be(true)
end

it 'returns true when the version is a float greater than 2.0' do
schema = Class.new(GraphQL::Schema) do
include ApolloFederation::Schema
federation version: 2.3
end

expect(schema.federation_2?).to be(true)
end

it 'returns true when the version is a string greater than 2.0' do
schema = Class.new(GraphQL::Schema) do
include ApolloFederation::Schema
Expand All @@ -69,5 +87,14 @@

expect(schema.federation_2?).to be(true)
end

it 'returns true when the version is a string greater than 2.0' do
schema = Class.new(GraphQL::Schema) do
include ApolloFederation::Schema
federation version: '2.3'
end

expect(schema.federation_2?).to be(true)
end
end
end
64 changes: 58 additions & 6 deletions spec/apollo-federation/service_field_v2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def execute_sdl(schema)
expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "fed2")
type Product @fed2__extends {
upc: String!
Expand Down Expand Up @@ -290,7 +290,7 @@ def execute_sdl(schema)
expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "fed2")
type Position @fed2__shareable {
x: Int!
Expand Down Expand Up @@ -327,7 +327,7 @@ def execute_sdl(schema)
expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "fed2")
type Position @fed2__inaccessible {
x: Int!
Expand Down Expand Up @@ -363,7 +363,7 @@ def execute_sdl(schema)
expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "fed2")
type Product @fed2__key(fields: "upc") {
upc: String!
Expand All @@ -376,7 +376,7 @@ def execute_sdl(schema)
)
end

it 'returns valid SDL for @external directives' do
it 'returns valid SDL for @external directives with custom namespace' do
product = Class.new(base_object) do
graphql_name 'Product'
extend_type
Expand All @@ -394,7 +394,7 @@ def execute_sdl(schema)
expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0")
@link(url: "https://specs.apollo.dev/federation/v2.0", as: "fed2")
type Product @fed2__extends @fed2__key(fields: "upc") {
price: Int
Expand All @@ -403,6 +403,32 @@ def execute_sdl(schema)
GRAPHQL
)
end

it 'returns valid SDL for @interfaceObject directives with custom namespace' do
product = Class.new(base_object) do
graphql_name 'Product'
interface_object
key fields: :id

field :id, 'ID', null: false
end

schema = Class.new(base_schema) do
orphan_types product
federation version: '2.3', link: { as: 'fed2' }
end

expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3", as: "fed2")
type Product @fed2__interfaceObject @fed2__key(fields: "id") {
id: ID!
}
GRAPHQL
)
end
end

it 'returns valid SDL for inaccessible interface types' do
Expand Down Expand Up @@ -644,6 +670,32 @@ def execute_sdl(schema)
)
end

it 'returns valid SDL for @interfaceObject directives' do
product = Class.new(base_object) do
graphql_name 'Product'
interface_object
key fields: :id

field :id, 'ID', null: false
end

schema = Class.new(base_schema) do
orphan_types product
federation version: '2.3'
end

expect(execute_sdl(schema)).to match_sdl(
<<~GRAPHQL,
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3")
type Product @federation__interfaceObject @federation__key(fields: "id") {
id: ID!
}
GRAPHQL
)
end

it 'returns valid SDL for @shareable directives' do
position = Class.new(base_object) do
graphql_name 'Position'
Expand Down

0 comments on commit b141d87

Please sign in to comment.