This repository is no longer relevant
- 🚀 If you want schema directives, upgrade
graphql-rubyto v2.0.16. - 🧵 If you want schema stitching, use
graphql-stitching-ruby.
This gem extends GraphQL Ruby to add support for custom schema directives that annotate an SDL for uses such as Schema Stitching. This is a more generic version of the apollo-federation gem (which is specifically tailored to setting up the federation spec).
This gem has some very basic goals:
- allow schema directives to be applied to any GraphQL element, and then printed as an annotated SDL.
- allow class-based schemas and parsed
GraphQL::Schema.from_definitionschemas to be printed together.
Add to Gemfile:
gem 'graphql-schema_directives'Then install:
bundle installThere's a typed mixin available for extending all GraphQL schema members. The first thing to include is the schema mixin:
class MySchema < GraphQL::Schema
include GraphQL::SchemaDirectives::Schema
endThis adds a print_schema_with_directives method to print an SDL that includes custom schema directives:
MySchema.print_schema_with_directivesSetup base abstracts:
class BaseField < GraphQL::Schema::Field
include GraphQL::SchemaDirectives::Field
end
class BaseObject < GraphQL::Schema::Object
include GraphQL::SchemaDirectives::Object
field_class BaseField
end
module BaseInterface
include GraphQL::Schema::Interface
include GraphQL::SchemaDirectives::Interface
field_class BaseField
endThen extend into concrete implementations:
module Spaceship
include BaseInterface
add_directive :attribute, { speed: 'average' }
field :name, String, null: false, directives: {
cost: { value: 'FIELD' },
public: nil
}
end
class XWing < BaseObject
implements Spaceship
add_directive :attribute, { speed: 'fast' }
add_directive :rebel
field :name, String, null: false, directives: {
cost: { value: 'FIELD' },
public: nil
}
endPrints as:
interface Spaceship @attribute(speed: "average") {
name: String! @cost(value: "FIELD") @public
}
type XWing @attribute(speed: "fast") @rebel {
name: String! @cost(value: "FIELD") @public
}Base abstracts:
class BaseArgument < GraphQL::Schema::Argument
include GraphQL::SchemaDirectives::Argument
end
class BaseInputObject < GraphQL::Schema::InputObject
include GraphQL::SchemaDirectives::InputObject
argument_class BaseArgument
endConcrete implementation:
class FormInput < BaseInputObject
add_directive :oneField
argument :choice, String, required: true, directives: {
cost: { value: 'INPUT' },
public: nil
}
endPrints as:
input FormInput @oneField {
choice: String! @cost(value: "INPUT") @public
}Base abstracts:
class BaseEnumValue < GraphQL::Schema::EnumValue
include GraphQL::SchemaDirectives::EnumValue
end
class BaseEnum < GraphQL::Schema::Enum
include GraphQL::SchemaDirectives::Enum
enum_value_class BaseEnumValue
endConcrete implementation:
class FormOption < BaseEnum
add_directive :dunno
value 'GET', directives: { cost: { value: 'READ' }, public: nil }
value 'SET', directives: { cost: { value: 'WRITE' }, public: nil }
endPrints as:
enum FormOption @dunno {
GET @cost(value: "READ") @public
SET @cost(value: "WRITE") @public
}Base abstracts:
class BaseUnion < GraphQL::Schema::Union
include GraphQL::SchemaDirectives::Union
end
class BaseScalar < GraphQL::Schema::Scalar
include GraphQL::SchemaDirectives::Scalar
endYou may also parse and print SDLs using the gem's from_definition method:
schema = GraphQL::SchemaDirectives.from_definition(type_defs)
puts schema.print_schema_with_directivesThe local from_definition method accepts all the same options as the underlying method. Calling print_schema_with_directives works exactly like the default printer when operating on an unmodified document parse (elements with an original AST will print their schema directives natively).
This feature becomes useful when you start modifying a parsed document with class-based additions:
module Spaceship
include GraphQL::Schema::Interface
include GraphQL::SchemaDirectives::Interface
field :name, String, null: false, directives: { public: nil }
end
type_defs = %(
type XWing {
name: String! @public
}
type Query {
ship: XWing
}
schema {
query: Query
}
)
schema = GraphQL::SchemaDirectives.from_definition(type_defs)
schema.types['XWing'].implements(Spaceship)
puts schema.print_schema_with_directivesUsing print_schema_with_directives will include directives from the original AST as well as directives applied to added classes.