Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More

graphql-schema_directives

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-schema_directives


Version published
Maintainers
1
Created

Ruby GraphQL Schema Directives

This gem extends GraphQL Ruby to add support for custom schema directives that annotate an SDL. These annotations are useful for Schema Stitching, Apollo Federation, and other proprietary uses.

This gem is intentionally generic, versus the apollo-federation gem upon which it is based. The goals of this gem are much simpler:

  1. allow schema directives to be applied to any GraphQL element, and then printed into an annotated SDL.
  2. allow class-based schemas and parsed GraphQL::Schema.from_definition schemas to be combined and printed together.

Table of Contents

Installation

Add to Gemfile:

gem 'graphql-schema_directives'

Then install:

bundle install

Class-based schemas

There's a typed mixin available for extending all GraphQL schema members.

Schema classes

Include the schema mixin:

class MySchema < GraphQL::Schema
  include GraphQL::SchemaDirectives::Schema
end

This adds a print_schema_with_directives method to print an SDL that includes custom schema directives:

MySchema.print_schema_with_directives

Field, Object & Interface classes

Setup 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
end

Then 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
  }
end

Prints from schema.print_schema_with_directives as:

interface Spaceship @attribute(speed: "average") {
  name: String! @cost(value: "FIELD") @public
}

type XWing @attribute(speed: "fast") @rebel {
  name: String! @cost(value: "FIELD") @public
}

Argument & InputObject classes

Base abstracts:

class BaseArgument < GraphQL::Schema::Argument
  include GraphQL::SchemaDirectives::Argument
end

class BaseInputObject < GraphQL::Schema::InputObject
  include GraphQL::SchemaDirectives::InputObject
  argument_class BaseArgument
end

Concrete implementation:

class FormInput < BaseInputObject
  add_directive :oneField
  argument :choice, String, required: true, directives: {
    cost: { value: 'INPUT' },
    public: nil
  }
end

Prints as:

input FormInput @oneField {
  choice: String! @cost(value: "INPUT") @public
}

EnumValue & Enum classes

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
end

Concrete implementation:

class FormOption < BaseEnum
  add_directive :dunno
  value 'GET', directives: { cost: { value: 'READ' }, public: nil }
  value 'SET', directives: { cost: { value: 'WRITE' }, public: nil }
end

Prints as:

enum FormOption @dunno {
  GET @cost(value: "READ") @public
  SET @cost(value: "WRITE") @public
}

Other classes

Base abstracts:

class BaseUnion < GraphQL::Schema::Union
  include GraphQL::SchemaDirectives::Union
end

class BaseScalar < GraphQL::Schema::Scalar
  include GraphQL::SchemaDirectives::Scalar
end

Schemas from definition

You 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_directives

The 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_directives

Using print_schema_with_directives will include directives from the original AST as well as directives applied to added classes.

FAQs

Package last updated on 27 Dec 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts