diff --git a/lib/graphql.rb b/lib/graphql.rb index af18b27f32..8fcf4540c0 100644 --- a/lib/graphql.rb +++ b/lib/graphql.rb @@ -44,6 +44,7 @@ def self.parse_with_parslet(string) require 'graphql/enum_type' require 'graphql/input_object_type' require 'graphql/interface_type' +require 'graphql/mixin' require 'graphql/list_type' require 'graphql/non_null_type' require 'graphql/union_type' diff --git a/lib/graphql/definition_helpers/defined_by_config.rb b/lib/graphql/definition_helpers/defined_by_config.rb index edd37ce86d..1e76523d45 100644 --- a/lib/graphql/definition_helpers/defined_by_config.rb +++ b/lib/graphql/definition_helpers/defined_by_config.rb @@ -52,6 +52,10 @@ def types GraphQL::DefinitionHelpers::TypeDefiner.instance end + def mixin(mixin) + @fields = mixin.fields.merge(@fields) + end + def field(name, type = nil, desc = nil, field: nil, property: nil, &block) if block_given? field = GraphQL::Field.define(&block) diff --git a/lib/graphql/mixin.rb b/lib/graphql/mixin.rb new file mode 100644 index 0000000000..0d6bc58528 --- /dev/null +++ b/lib/graphql/mixin.rb @@ -0,0 +1,7 @@ +module GraphQL + class Mixin + include GraphQL::DefinitionHelpers::DefinedByConfig + defined_by_config :fields + attr_accessor :fields + end +end diff --git a/spec/graphql/introspection/type_type_spec.rb b/spec/graphql/introspection/type_type_spec.rb index 71b857d6d5..bd6fe47759 100644 --- a/spec/graphql/introspection/type_type_spec.rb +++ b/spec/graphql/introspection/type_type_spec.rb @@ -12,6 +12,8 @@ |} let(:result) { DummySchema.execute(query_string, context: {}, variables: {"cheeseId" => 2}) } let(:cheese_fields) {[ + {"name"=>"cents", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "Int"}}}, + {"name"=>"currency", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "String"}}}, {"name"=>"id", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "Int"}}}, {"name"=>"flavor", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "String"}}}, {"name"=>"origin", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "String"}}}, @@ -37,7 +39,9 @@ {"name"=>"AnimalProduct"} ], "fields"=>[ - {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"ID"}}}, + {"type"=>{"name"=>"Non-Null","ofType"=>{"name"=>"Int"}}}, + {"type"=>{"name"=>"Non-Null","ofType"=>{"name"=>"String"}}}, + {"type"=>{"name"=>"Non-Null","ofType"=>{"name"=>"ID"}}}, {"type"=>{"name"=>"DairyAnimal", "ofType"=>nil}}, {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"String"}}}, {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}}, diff --git a/spec/support/dairy_app.rb b/spec/support/dairy_app.rb index 16019cf6c6..bf80b22c25 100644 --- a/spec/support/dairy_app.rb +++ b/spec/support/dairy_app.rb @@ -24,11 +24,16 @@ class NoSuchDairyError < StandardError; end value("YAK", "Animal with long hair", deprecation_reason: "Out of fashion") end +HasPrice = GraphQL::Mixin.define do + field :cents, !types.Int + field :currency, !types.String +end + CheeseType = GraphQL::ObjectType.define do name "Cheese" description "Cultured dairy product" interfaces [EdibleInterface, AnimalProductInterface] - + mixin HasPrice # Can have (name, type, desc) field :id, !types.Int, "Unique identifier" field :flavor, !types.String, "Kind of Cheese" @@ -62,6 +67,7 @@ class NoSuchDairyError < StandardError; end name 'Milk' description "Dairy beverage" interfaces [EdibleInterface, AnimalProductInterface] + mixin HasPrice field :id, !types.ID field :source, DairyAnimalEnum, "Animal which produced this milk" field :origin, !types.String, "Place the milk comes from"