Class: GraphQL::Schema::Object
- Extended by:
- Member::AcceptsDefinition, Member::HasFields
- Defined in:
- lib/graphql/schema/object.rb
Direct Known Subclasses
Introspection::BaseObject, Types::Relay::BaseConnection, Types::Relay::BaseEdge, Types::Relay::PageInfo
Constant Summary
Constants included from Member::HasFields
Member::HasFields::CONFLICT_FIELD_NAMES, Member::HasFields::GRAPHQL_RUBY_KEYWORDS, Member::HasFields::RUBY_KEYWORDS
Constants included from Member::HasDirectives
Member::HasDirectives::NO_DIRECTIVES
Constants included from Member::GraphQLTypeNames
Member::GraphQLTypeNames::Boolean, Member::GraphQLTypeNames::ID, Member::GraphQLTypeNames::Int
Instance Attribute Summary collapse
-
#context ⇒ GraphQL::Query::Context
readonly
The context instance for this query.
-
#object ⇒ Object
readonly
The application object this type is wrapping.
Class Method Summary collapse
-
.authorized_new(object, context) ⇒ GraphQL::Schema::Object, GraphQL::Execution::Lazy
Make a new instance of this type if the auth check passes, otherwise, raise an error.
-
.fields ⇒ Hash<String => GraphQL::Schema::Field>
All of this object’s fields, indexed by name.
-
.implements(*new_interfaces, **options) ⇒ Object
-
.inherited(child_class) ⇒ Object
Set up a type-specific invalid null error to use when this object’s non-null fields wrongly return
nil
. -
.interface_type_memberships ⇒ Object
-
.interfaces(context = GraphQL::Query::NullContext) ⇒ Object
param context [Query::Context] If omitted, skip filtering.
-
.kind ⇒ Object
-
.own_interface_type_memberships ⇒ Object
-
.to_graphql ⇒ GraphQL::ObjectType
Instance Method Summary collapse
-
#dataloader ⇒ GraphQL::Dataloader
-
#initialize(object, context) ⇒ Object
constructor
A new instance of Object.
-
#raw_value(obj) ⇒ Object
Call this in a field method to return a value that should be returned to the client without any further handling by GraphQL.
Methods included from Member::HasFields
add_field, field, field_class, fields, get_field, global_id_field, own_fields
Methods included from Member::CachedGraphQLDefinition
#graphql_definition, #initialize_copy, #type_class
Methods included from Relay::TypeExtensions
#connection_type, #define_connection, #define_edge, #edge_type
Methods included from Member::BaseDSLMethods
#accessible?, #authorized?, #default_graphql_name, #description, #graphql_name, #introspection, #introspection?, #mutation, #name, #overridden_graphql_name, #to_graphql, #visible?
Methods included from Member::BaseDSLMethods::ConfigurationExtension
Methods included from Member::TypeSystemHelpers
#kind, #list?, #non_null?, #to_list_type, #to_non_null_type, #to_type_signature
Methods included from Member::Scoped
Methods included from Member::RelayShortcuts
#connection_type, #connection_type_class, #edge_type, #edge_type_class
Methods included from Member::HasPath
Methods included from Member::HasAstNode
Methods included from Member::HasDirectives
#directive, #directives, #remove_directive
Constructor Details
#initialize(object, context) ⇒ Object
Returns a new instance of Object.
93 94 95 96 |
# File 'lib/graphql/schema/object.rb', line 93 def initialize(object, context) @object = object @context = context end |
Instance Attribute Details
#context ⇒ GraphQL::Query::Context (readonly)
Returns the context instance for this query.
15 16 17 |
# File 'lib/graphql/schema/object.rb', line 15 def context @context end |
#object ⇒ Object (readonly)
Returns the application object this type is wrapping.
12 13 14 |
# File 'lib/graphql/schema/object.rb', line 12 def object @object end |
Class Method Details
.authorized_new(object, context) ⇒ GraphQL::Schema::Object, GraphQL::Execution::Lazy
Make a new instance of this type if the auth check passes, otherwise, raise an error.
Probably only the framework should call this method.
This might return a Execution::Lazy if the user-provided .authorized?
hook returns some lazy value (like a Promise).
The reason that the auth check is in this wrapper method instead of new is because
of how it might return a Promise. It would be weird if .new
returned a promise;
It would be a headache to try to maintain Promise-y state inside a GraphQL::Schema::Object
instance. So, hopefully this wrapper method will do the job.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/graphql/schema/object.rb', line 50 def (object, context) trace_payload = { context: context, type: self, object: object, path: context[:current_path] } maybe_lazy_auth_val = context.query.trace("authorized", trace_payload) do context.query.with_error_handling do begin (object, context) rescue GraphQL::UnauthorizedError => err context.schema.(err) end end end auth_val = if context.schema.lazy?(maybe_lazy_auth_val) GraphQL::Execution::Lazy.new do context.query.trace("authorized_lazy", trace_payload) do context.schema.sync_lazy(maybe_lazy_auth_val) end end else maybe_lazy_auth_val end context.schema.after_lazy(auth_val) do || if self.new(object, context) else # It failed the authorization check, so go to the schema's authorized object hook err = GraphQL::UnauthorizedError.new(object: object, type: self, context: context) # If a new value was returned, wrap that instead of the original value begin new_obj = context.schema.(err) if new_obj self.new(new_obj, context) else nil end end end end end |
.fields ⇒ Hash<String => GraphQL::Schema::Field>
Returns All of this object’s fields, indexed by name.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/graphql/schema/object.rb', line 177 def fields all_fields = super interfaces.each do |int| # Include legacy-style interfaces, too if int.is_a?(GraphQL::InterfaceType) int_f = {} int.fields.each do |name, legacy_field| int_f[name] = field_class.(name, field: legacy_field) end all_fields = int_f.merge(all_fields) end end all_fields end |
.implements(*new_interfaces, **options) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/graphql/schema/object.rb', line 106 def implements(*new_interfaces, **) new_memberships = [] new_interfaces.each do |int| if int.is_a?(Module) unless int.include?(GraphQL::Schema::Interface) raise "#{int} cannot be implemented since it's not a GraphQL Interface. Use `include` for plain Ruby modules." end new_memberships << int.type_membership_class.new(int, self, **) # Include the methods here, # `.fields` will use the inheritance chain # to find inherited fields include(int) elsif int.is_a?(GraphQL::InterfaceType) new_memberships << int.type_membership_class.new(int, self, **) elsif int.is_a?(String) || int.is_a?(GraphQL::Schema::LateBoundType) if .any? raise ArgumentError, "`implements(...)` doesn't support options with late-loaded types yet. Remove #{} and open an issue to request this feature." end new_memberships << int else raise ArgumentError, "Unexpected interface definition (expected module): #{int} (#{int.class})" end end # Remove any interfaces which are being replaced (late-bound types are updated in place this way) own_interface_type_memberships.reject! { |old_i_m| old_int_type = old_i_m.respond_to?(:abstract_type) ? old_i_m.abstract_type : old_i_m old_name = Schema::Member::BuildType.to_type_name(old_int_type) new_memberships.any? { |new_i_m| new_int_type = new_i_m.respond_to?(:abstract_type) ? new_i_m.abstract_type : new_i_m new_name = Schema::Member::BuildType.to_type_name(new_int_type) new_name == old_name } } own_interface_type_memberships.concat(new_memberships) end |
.inherited(child_class) ⇒ Object
Set up a type-specific invalid null error to use when this object’s non-null fields wrongly return nil
.
It should help with debugging and bug tracker integrations.
101 102 103 104 |
# File 'lib/graphql/schema/object.rb', line 101 def inherited(child_class) child_class.const_set(:InvalidNullError, GraphQL::InvalidNullError.subclass_for(child_class)) super end |
.interface_type_memberships ⇒ Object
151 152 153 |
# File 'lib/graphql/schema/object.rb', line 151 def interface_type_memberships own_interface_type_memberships + (superclass.respond_to?(:interface_type_memberships) ? superclass.interface_type_memberships : []) end |
.interfaces(context = GraphQL::Query::NullContext) ⇒ Object
param context [Query::Context] If omitted, skip filtering.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/graphql/schema/object.rb', line 156 def interfaces(context = GraphQL::Query::NullContext) visible_interfaces = [] unfiltered = context == GraphQL::Query::NullContext own_interface_type_memberships.each do |type_membership| # During initialization, `type_memberships` can hold late-bound types case type_membership when String, Schema::LateBoundType visible_interfaces << type_membership when Schema::TypeMembership if unfiltered || type_membership.visible?(context) visible_interfaces << type_membership.abstract_type end else raise "Invariant: Unexpected type_membership #{type_membership.class}: #{type_membership.inspect}" end end visible_interfaces + (superclass <= GraphQL::Schema::Object ? superclass.interfaces(context) : []) end |
.kind ⇒ Object
211 212 213 |
# File 'lib/graphql/schema/object.rb', line 211 def kind GraphQL::TypeKinds::OBJECT end |
.own_interface_type_memberships ⇒ Object
147 148 149 |
# File 'lib/graphql/schema/object.rb', line 147 def own_interface_type_memberships @own_interface_type_memberships ||= [] end |
.to_graphql ⇒ GraphQL::ObjectType
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/graphql/schema/object.rb', line 193 def to_graphql obj_type = GraphQL::ObjectType.new obj_type.name = graphql_name obj_type.description = description obj_type.structural_interface_type_memberships = interface_type_memberships obj_type.introspection = introspection obj_type.mutation = mutation obj_type.ast_node = ast_node fields.each do |field_name, field_inst| field_defn = field_inst.to_graphql obj_type.fields[field_defn.name] = field_defn end obj_type.[:type_class] = self obj_type end |
Instance Method Details
#dataloader ⇒ GraphQL::Dataloader
18 19 20 |
# File 'lib/graphql/schema/object.rb', line 18 def dataloader context.dataloader end |