Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gmac/graphql-ruby-schema-directives
Generic implementation of schema directives for GraphQL Ruby
https://github.com/gmac/graphql-ruby-schema-directives
apollo-federation graphql graphql-ruby schema-directives schema-stitching sdl
Last synced: about 1 month ago
JSON representation
Generic implementation of schema directives for GraphQL Ruby
- Host: GitHub
- URL: https://github.com/gmac/graphql-ruby-schema-directives
- Owner: gmac
- License: mit
- Archived: true
- Created: 2020-12-24T19:07:42.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2023-02-10T21:43:36.000Z (almost 2 years ago)
- Last Synced: 2024-10-27T22:47:25.752Z (2 months ago)
- Topics: apollo-federation, graphql, graphql-ruby, schema-directives, schema-stitching, sdl
- Language: Ruby
- Homepage:
- Size: 22.5 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
**This repository is no longer relevant**
- ๐ If you want schema directives, upgrade [`graphql-ruby`](https://github.com/rmosolgo/graphql-ruby) to v2.0.16.
- ๐งต If you want schema stitching, use [`graphql-stitching-ruby`](https://github.com/gmac/graphql-stitching-ruby).## Ruby GraphQL Schema Directives
This gem extends [GraphQL Ruby](http://graphql-ruby.org/) to add support for custom schema directives that annotate an SDL for uses such as [Schema Stitching](https://github.com/gmac/schema-stitching-handbook/tree/master/subservice-languages/ruby). This is a more generic version of the [apollo-federation](https://github.com/Gusto/apollo-federation-ruby) gem (which is specifically tailored to setting up the [federation spec](https://www.apollographql.com/docs/federation/federation-spec/)).
This gem has some very basic goals:
1. allow schema directives to be applied to any GraphQL element, and then printed as an annotated SDL.
2. allow class-based schemas and parsed `GraphQL::Schema.from_definition` schemas to be printed together.## Contents
- [Installation](#installation)
- [Class-based schemas](#class-based-schemas)
- [Schema from type definitions](#schema-from-type-definitions)## Installation
Add to Gemfile:
```ruby
gem 'graphql-schema_directives'
```Then install:
```shell
bundle install
```## Class-based schemas
There's a typed mixin available for extending all GraphQL schema members. The first thing to include is the schema mixin:
```ruby
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:
```ruby
MySchema.print_schema_with_directives
```### Field, Object & Interface classes
Setup base abstracts:
```ruby
class BaseField < GraphQL::Schema::Field
include GraphQL::SchemaDirectives::Field
endclass BaseObject < GraphQL::Schema::Object
include GraphQL::SchemaDirectives::Object
field_class BaseField
endmodule BaseInterface
include GraphQL::Schema::Interface
include GraphQL::SchemaDirectives::Interface
field_class BaseField
end
```Then extend into concrete implementations:
```ruby
module Spaceship
include BaseInterface
add_directive :attribute, { speed: 'average' }field :name, String, null: false, directives: {
cost: { value: 'FIELD' },
public: nil
}
endclass XWing < BaseObject
implements Spaceship
add_directive :attribute, { speed: 'fast' }
add_directive :rebelfield :name, String, null: false, directives: {
cost: { value: 'FIELD' },
public: nil
}
end
```Prints as:
```graphql
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:
```ruby
class BaseArgument < GraphQL::Schema::Argument
include GraphQL::SchemaDirectives::Argument
endclass BaseInputObject < GraphQL::Schema::InputObject
include GraphQL::SchemaDirectives::InputObject
argument_class BaseArgument
end
```Concrete implementation:
```ruby
class FormInput < BaseInputObject
add_directive :oneField
argument :choice, String, required: true, directives: {
cost: { value: 'INPUT' },
public: nil
}
end
```Prints as:
```graphql
input FormInput @oneField {
choice: String! @cost(value: "INPUT") @public
}
```### EnumValue & Enum classes
Base abstracts:
```ruby
class BaseEnumValue < GraphQL::Schema::EnumValue
include GraphQL::SchemaDirectives::EnumValue
endclass BaseEnum < GraphQL::Schema::Enum
include GraphQL::SchemaDirectives::Enum
enum_value_class BaseEnumValue
end
```Concrete implementation:
```ruby
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:
```graphql
enum FormOption @dunno {
GET @cost(value: "READ") @public
SET @cost(value: "WRITE") @public
}
```### Other classes
Base abstracts:
```ruby
class BaseUnion < GraphQL::Schema::Union
include GraphQL::SchemaDirectives::Union
endclass BaseScalar < GraphQL::Schema::Scalar
include GraphQL::SchemaDirectives::Scalar
end
```## Schema from type definitions
You may also [parse and print SDLs](https://graphql-ruby.org/schema/sdl.html) using the gem's `from_definition` method:
```rb
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](https://graphql-ruby.org/api-doc/1.11.6/GraphQL/Schema#from_definition-class_method). Calling `print_schema_with_directives` works exactly like the [default printer](https://graphql-ruby.org/api-doc/1.11.6/GraphQL/Language/Printer.html#print-instance_method) 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:
```rb
module Spaceship
include GraphQL::Schema::Interface
include GraphQL::SchemaDirectives::Interface
field :name, String, null: false, directives: { public: nil }
endtype_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.