Class: GraphQL::Schema
- Inherits:
-
Object
- Object
- GraphQL::Schema
- Extended by:
- Autoload, FindInheritedValue, Member::HasAstNode
- Defined in:
- lib/graphql/schema.rb,
lib/graphql/schema/enum.rb,
lib/graphql/schema/list.rb,
lib/graphql/schema/field.rb,
lib/graphql/schema/union.rb,
lib/graphql/schema/finder.rb,
lib/graphql/schema/loader.rb,
lib/graphql/schema/member.rb,
lib/graphql/schema/object.rb,
lib/graphql/schema/scalar.rb,
lib/graphql/schema/warden.rb,
lib/graphql/schema/printer.rb,
lib/graphql/schema/timeout.rb,
lib/graphql/schema/wrapper.rb,
lib/graphql/schema/addition.rb,
lib/graphql/schema/argument.rb,
lib/graphql/schema/mutation.rb,
lib/graphql/schema/non_null.rb,
lib/graphql/schema/resolver.rb,
lib/graphql/schema/directive.rb,
lib/graphql/schema/interface.rb,
lib/graphql/schema/validator.rb,
lib/graphql/schema/enum_value.rb,
lib/graphql/schema/visibility.rb,
lib/graphql/schema/input_object.rb,
lib/graphql/schema/subscription.rb,
lib/graphql/schema/member/scoped.rb,
lib/graphql/schema/always_visible.rb,
lib/graphql/schema/built_in_types.rb,
lib/graphql/schema/directive/skip.rb,
lib/graphql/schema/base_64_encoder.rb,
lib/graphql/schema/field_extension.rb,
lib/graphql/schema/late_bound_type.rb,
lib/graphql/schema/member/has_path.rb,
lib/graphql/schema/type_expression.rb,
lib/graphql/schema/type_membership.rb,
lib/graphql/schema/directive/one_of.rb,
lib/graphql/schema/ractor_shareable.rb,
lib/graphql/schema/visibility/visit.rb,
lib/graphql/schema/directive/feature.rb,
lib/graphql/schema/directive/flagged.rb,
lib/graphql/schema/directive/include.rb,
lib/graphql/schema/member/build_type.rb,
lib/graphql/schema/member/has_fields.rb,
lib/graphql/schema/unique_within_type.rb,
lib/graphql/schema/visibility/profile.rb,
lib/graphql/schema/directive/transform.rb,
lib/graphql/schema/member/has_ast_node.rb,
lib/graphql/schema/directive/deprecated.rb,
lib/graphql/schema/find_inherited_value.rb,
lib/graphql/schema/introspection_system.rb,
lib/graphql/schema/member/has_arguments.rb,
lib/graphql/schema/visibility/migration.rb,
lib/graphql/schema/build_from_definition.rb,
lib/graphql/schema/field/scope_extension.rb,
lib/graphql/schema/member/has_dataloader.rb,
lib/graphql/schema/member/has_directives.rb,
lib/graphql/schema/member/has_interfaces.rb,
lib/graphql/schema/member/has_validators.rb,
lib/graphql/schema/directive/specified_by.rb,
lib/graphql/schema/member/relay_shortcuts.rb,
lib/graphql/schema/member/validates_input.rb,
lib/graphql/schema/relay_classic_mutation.rb,
lib/graphql/schema/member/base_dsl_methods.rb,
lib/graphql/schema/validator/all_validator.rb,
lib/graphql/schema/has_single_input_argument.rb,
lib/graphql/schema/member/graphql_type_names.rb,
lib/graphql/schema/resolver/has_payload_type.rb,
lib/graphql/schema/field/connection_extension.rb,
lib/graphql/schema/member/type_system_helpers.rb,
lib/graphql/schema/validator/format_validator.rb,
lib/graphql/schema/validator/length_validator.rb,
lib/graphql/schema/validator/required_validator.rb,
lib/graphql/schema/member/has_deprecation_reason.rb,
lib/graphql/schema/validator/exclusion_validator.rb,
lib/graphql/schema/validator/inclusion_validator.rb,
lib/graphql/schema/validator/allow_null_validator.rb,
lib/graphql/schema/validator/allow_blank_validator.rb,
lib/graphql/schema/member/has_unresolved_type_error.rb,
lib/graphql/schema/validator/numericality_validator.rb,
lib/graphql/schema/build_from_definition/resolve_map.rb,
lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb
Overview
A GraphQL schema which may be queried with Query.
The Schema contains:
- types for exposing your application
- query analyzers for assessing incoming queries (including max depth & max complexity restrictions)
- execution strategies for running incoming queries
Schemas start with root types, Schema.query, Schema.mutation and Schema.subscription.
The schema will traverse the tree of fields & types, using those as starting points.
Any undiscoverable types may be provided with the types configuration.
Schemas can restrict large incoming queries with max_depth and max_complexity configurations.
(These configurations can be overridden by specific calls to Schema.execute)
Direct Known Subclasses
Defined Under Namespace
Modules: AlwaysVisible, Base64Encoder, BuildFromDefinition, DefaultTraceClass, FindInheritedValue, HasSingleInputArgument, Interface, Loader, RactorShareable, ResolveTypeWithType, SubclassGetReferencesTo, TypeExpression, UniqueWithinType Classes: Addition, Argument, Directive, DuplicateNamesError, Enum, EnumValue, Field, FieldExtension, Finder, InputObject, IntrospectionSystem, InvalidDocumentError, LateBoundType, List, Member, Mutation, NonNull, Object, Printer, RelayClassicMutation, Resolver, Scalar, Subscription, Timeout, TypeMembership, Union, UnresolvedLateBoundTypeError, Validator, Visibility, Warden, Wrapper
Constant Summary collapse
- BUILT_IN_TYPES =
{ "Int" => GraphQL::Types::Int, "String" => GraphQL::Types::String, "Float" => GraphQL::Types::Float, "Boolean" => GraphQL::Types::Boolean, "ID" => GraphQL::Types::ID, }
Class Attribute Summary collapse
-
.analysis_engine ⇒ Object
-
.connections ⇒ GraphQL::Pagination::Connections
If installed.
-
.dataloader_class ⇒ Object
private
-
.detailed_trace ⇒ GraphQL::Tracing::DetailedTrace
If it has been configured for this schema.
-
.error_bubbling(new_error_bubbling = nil) ⇒ Object
-
.max_complexity(max_complexity = nil, count_introspection_fields: true) ⇒ Object
-
.max_depth(new_max_depth = nil, count_introspection_fields: true) ⇒ Object
-
.null_context ⇒ Object
-
.use_visibility_profile ⇒ Object
writeonly
private
-
.using_backtrace ⇒ Object
private
-
.validate_max_errors(new_validate_max_errors = NOT_CONFIGURED) ⇒ Object
-
.validate_timeout(new_validate_timeout = NOT_CONFIGURED) ⇒ Object
-
.visibility ⇒ Object
private
-
.visibility_profile_class ⇒ Object
private
-
.warden_class ⇒ Object
private
Attributes included from Member::HasAstNode
Class Method Summary collapse
-
.add_subscription_extension_if_necessary ⇒ Object
private
-
.after_any_lazies(maybe_lazies) ⇒ Object
private
Return a lazy if any of
maybe_laziesare lazy, otherwise, call the block eagerly and return the result. -
.after_lazy(value, &block) ⇒ Object
private
Call the given block at the right time, either: - Right away, if
valueis not registered withlazy_resolve- After resolvingvalue, if it’s registered withlazy_resolve(eg,Promise). -
.allow_legacy_invalid_empty_selections_on_union(new_value = NOT_CONFIGURED) ⇒ true, ...
This setting controls how GraphQL-Ruby handles empty selections on Union types.
-
.allow_legacy_invalid_return_type_conflicts(new_value = NOT_CONFIGURED) ⇒ true, ...
This setting controls how GraphQL-Ruby handles overlapping selections on scalar types when the types don’t match.
-
.as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false) ⇒ Hash
Return the Hash response of Introspection::INTROSPECTION_QUERY.
-
.build_trace_mode(mode) ⇒ Object
-
.complexity_cost_calculation_mode(new_mode = NOT_CONFIGURED) ⇒ Object
The legacy complexity implementation included several bugs:.
-
.complexity_cost_calculation_mode_for(multiplex_context) ⇒ :future, ...
Implement this method to produce a per-query complexity cost calculation mode.
-
.context_class(new_context_class = nil) ⇒ Object
-
.count_introspection_fields ⇒ Object
-
.cursor_encoder(new_encoder = nil) ⇒ Object
-
.default_analysis_engine ⇒ Object
-
.default_directives ⇒ Object
-
.default_execution_strategy ⇒ Object
-
.default_logger(new_default_logger = NOT_CONFIGURED) ⇒ Object
-
.default_max_page_size(new_default_max_page_size = nil) ⇒ Object
-
.default_page_size(new_default_page_size = nil) ⇒ Object
-
.default_trace_mode(new_mode = NOT_CONFIGURED) ⇒ Object
-
.deprecated_graphql_definition ⇒ Object
-
.description(new_description = nil) ⇒ String?
-
.detailed_trace?(query) ⇒ Boolean
When
true, save a detailed trace for this query. -
.did_you_mean(new_dym = NOT_CONFIGURED) ⇒ Object
Returns
DidYouMeanif it’s defined. -
.directive(new_directive) ⇒ Object
Attach a single directive to this schema.
-
.directives(*new_directives) ⇒ Object
Add several directives at once.
-
.disable_introspection_entry_points ⇒ Object
-
.disable_introspection_entry_points? ⇒ Boolean
-
.disable_schema_introspection_entry_point ⇒ Object
-
.disable_schema_introspection_entry_point? ⇒ Boolean
-
.disable_type_introspection_entry_point ⇒ Object
-
.disable_type_introspection_entry_point? ⇒ Boolean
-
.error_handlers ⇒ Object
-
.execute(query_str = nil, **kwargs) ⇒ GraphQL::Query::Result
Execute a query on itself.
-
.extra_types(*new_extra_types) ⇒ Array<Module>
Type definitions added to this schema.
-
.find(path) ⇒ Object
-
.from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {}, base_types: {}) ⇒ Class
Create schema from an IDL schema or file containing an IDL definition.
-
.from_introspection(introspection_result) ⇒ Class<GraphQL::Schema>
Create schema with the result of an introspection query.
-
.get_field(type_or_name, field_name, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Object
-
.get_fields(type, context = null_context) ⇒ Object
-
.get_type(type_name, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Module?
A type, or nil if there’s no type called
type_name. -
.handle_or_reraise(context, err) ⇒ Object
private
-
.has_defined_type?(type_name) ⇒ Boolean
Does this schema have any definition for a type named
type_name, regardless of visibility?. -
.id_from_object(application_object, graphql_type, context) ⇒ String
Return a stable ID string for
objectso that it can be refetched later, using Schema.object_from_id. -
.inherited(child_class) ⇒ Object
rubocop:enable Lint/DuplicateMethods.
-
.instrument(instrument_step, instrumenter, options = {}) ⇒ Object
-
.instrumenters ⇒ Object
-
.introspection(new_introspection_namespace = nil) ⇒ Module?
Pass a custom introspection module here to use it for this schema.
-
.introspection_system ⇒ Schema::IntrospectionSystem
Based on Schema.introspection.
-
.lazy?(obj) ⇒ Boolean
True if this object should be lazily resolved.
-
.lazy_method_name(obj) ⇒ Symbol?
The method name to lazily resolve
obj, or nil ifobj’s class wasn’t registered with Schema.lazy_resolve. -
.lazy_resolve(lazy_class, value_method) ⇒ Object
-
.legacy_complexity_cost_calculation_mismatch(multiplex, future_complexity_cost, legacy_complexity_cost) ⇒ Integer
Implement this method in your schema to handle mismatches when
:compareis used. -
.legacy_invalid_empty_selections_on_union(query) ⇒ :return_validation_error, ...
This method is called during validation when a previously-allowed, but non-spec query is encountered where a union field has no child selections on it.
-
.legacy_invalid_empty_selections_on_union_with_type(query, type) ⇒ :return_validation_error, ...
This method is called during validation when a previously-allowed, but non-spec query is encountered where a union field has no child selections on it.
-
.legacy_invalid_return_type_conflicts(query, type1, type2, node1, node2) ⇒ :return_validation_error, ...
This method is called when the query contains fields which don’t contain matching scalar types.
-
.load_type(type_name, ctx) ⇒ Object
Called when a type is needed by name at runtime.
-
.logger_for(context) ⇒ Logger
A logger to use for this context configuration, falling back to Schema.default_logger.
-
.max_complexity_count_introspection_fields ⇒ Object
-
.max_query_string_tokens(new_max_tokens = NOT_CONFIGURED) ⇒ nil, Integer
A limit on the number of tokens to accept on incoming query strings.
-
.multiplex(queries, **kwargs) ⇒ Array<GraphQL::Query::Result>
Execute several queries on itself, concurrently.
-
.multiplex_analyzer(new_analyzer) ⇒ Object
-
.multiplex_analyzers ⇒ Object
-
.mutation(new_mutation_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root
mutation { ... }object for this schema. -
.mutation_execution_strategy(new_mutation_execution_strategy = nil, deprecation_warning: true) ⇒ Object
-
.new_trace(mode: nil, **options) ⇒ Tracing::Trace
Create a trace instance which will include the trace modules specified for the optional mode.
-
.object_from_id(object_id, context) ⇒ Object?
Fetch an object based on an incoming ID and the current context.
-
.orphan_types(*new_orphan_types) ⇒ Array<Class<GraphQL::Schema::Object>>
Tell the schema about these types so that they can be registered as implementations of interfaces in the schema.
-
.own_trace_modes ⇒ Object
-
.own_trace_modules ⇒ Object
-
.parse_error(parse_err, ctx) ⇒ Object
A function to call when Schema.execute receives an invalid query string.
-
.plugins ⇒ Object
-
.possible_types(type = nil, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Hash<String, Module>, Array<Module>
-
.query(new_query_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root
query { ... }object for this schema. -
.query_analyzer(new_analyzer) ⇒ Object
-
.query_analyzers ⇒ Object
-
.query_class(new_query_class = NOT_CONFIGURED) ⇒ Object
-
.query_execution_strategy(new_query_execution_strategy = nil, deprecation_warning: true) ⇒ Object
-
.query_stack_error(query, err) ⇒ void
Called when execution encounters a
SystemStackError. -
.references_to(to_type = nil, from: nil) ⇒ Object
-
.rescue_from(*err_classes, &handler_block) {|error, object, arguments, context| ... } ⇒ Object
Register a handler for errors raised during execution.
-
.resolve_type(abstract_type, application_object, context) ⇒ Class<GraphQL::Schema::Object] The Object type definition to use for `obj`
GraphQL-Ruby calls this method during execution when it needs the application to determine the type to use for an object.
-
.resolves_lazies? ⇒ Boolean
-
.root_type_for_operation(operation) ⇒ Object
private
-
.root_types ⇒ Array<Class>
The root types (query, mutation, subscription) defined for this schema.
-
.sanitized_printer(new_sanitized_printer = nil) ⇒ Object
-
.schema_directive(dir_class, **options) ⇒ Object
-
.schema_directives ⇒ Object
-
.static_validator ⇒ Object
-
.subscription(new_subscription_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root
subscription { ... }object for this schema. -
.subscription_execution_strategy(new_subscription_execution_strategy = nil, deprecation_warning: true) ⇒ Object
-
.subscriptions(inherited: true) ⇒ GraphQL::Subscriptions
-
.subscriptions=(new_implementation) ⇒ Object
-
.sync_lazy(value) ⇒ Object
private
Override this method to handle lazy objects in a custom way.
-
.to_definition(context: {}) ⇒ String
Return the GraphQL IDL for the schema.
-
.to_document ⇒ GraphQL::Language::Document
Return the GraphQL::Language::Document IDL AST for the schema.
-
.to_json(**args) ⇒ String
Returns the JSON response of Introspection::INTROSPECTION_QUERY.
-
.trace_class(new_class = nil) ⇒ Object
-
.trace_class_for(mode, build: false) ⇒ Class
Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn’t have one defined.
-
.trace_mode(mode_name, trace_class) ⇒ Object
Configure
trace_classto be used whenevercontext: { trace_mode: mode_name }is requested. -
.trace_modules_for(trace_mode) ⇒ Array<Module>
Modules added for tracing in
trace_mode, including inherited ones. -
.trace_options_for(mode) ⇒ Hash
The options hash for this trace mode.
-
.trace_with(trace_mod, mode: :default, **options) ⇒ void
Mix
trace_modinto this schema’sTraceclass so that its methods will be called at runtime. -
.tracer(new_tracer, silence_deprecation_warning: false) ⇒ Object
-
.tracers ⇒ Object
-
.type_error(type_error, context) ⇒ void
Called at runtime when GraphQL-Ruby encounters a mismatch between the application behavior and the GraphQL type system.
-
.type_from_ast(ast_node, context: self.query_class.new(self, "{ __typename }").context) ⇒ Object
-
.types(context = null_context) ⇒ Hash<String => Class>
Build a map of
{ name => type }and return it. -
.unauthorized_field(unauthorized_error) ⇒ Field
This hook is called when a field fails an
authorized?check. -
.unauthorized_object(unauthorized_error) ⇒ Object
This hook is called when an object fails an
authorized?check. -
.union_memberships(type = nil) ⇒ Object
-
.use(plugin, **kwargs) ⇒ Object
Add
pluginto this schema. -
.use_visibility_profile? ⇒ Boolean
private
-
.uses_raw_value(new_val) ⇒ Object
-
.uses_raw_value? ⇒ Boolean
-
.validate(string_or_document, rules: nil, context: nil) ⇒ Array<GraphQL::StaticValidation::Error >
Validate a query string according to this schema.
-
.visible?(member, ctx) ⇒ Boolean
Methods included from Member::HasAstNode
Methods included from Autoload
Class Attribute Details
.analysis_engine ⇒ Object
917 918 919 |
# File 'lib/graphql/schema.rb', line 917 def analysis_engine @analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine) end |
.connections ⇒ GraphQL::Pagination::Connections
Returns if installed.
423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/graphql/schema.rb', line 423 def connections if defined?(@connections) @connections else inherited_connections = find_inherited_value(:connections, nil) # This schema is part of an inheritance chain which is using new connections, # make a new instance, so we don't pollute the upstream one. if inherited_connections @connections = Pagination::Connections.new(schema: self) else nil end end end |
.dataloader_class ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
679 680 681 |
# File 'lib/graphql/schema.rb', line 679 def dataloader_class @dataloader_class || GraphQL::Dataloader::NullDataloader end |
.detailed_trace ⇒ GraphQL::Tracing::DetailedTrace
Returns if it has been configured for this schema.
1430 1431 1432 |
# File 'lib/graphql/schema.rb', line 1430 def detailed_trace @detailed_trace end |
.error_bubbling(new_error_bubbling = nil) ⇒ Object
921 922 923 924 925 926 927 928 |
# File 'lib/graphql/schema.rb', line 921 def error_bubbling(new_error_bubbling = nil) if !new_error_bubbling.nil? warn("error_bubbling(#{new_error_bubbling.inspect}) is deprecated; the default value of `false` will be the only option in GraphQL-Ruby 3.0") @error_bubbling = new_error_bubbling else @error_bubbling.nil? ? find_inherited_value(:error_bubbling) : @error_bubbling end end |
.max_complexity(max_complexity = nil, count_introspection_fields: true) ⇒ Object
896 897 898 899 900 901 902 903 904 905 |
# File 'lib/graphql/schema.rb', line 896 def max_complexity(max_complexity = nil, count_introspection_fields: true) if max_complexity @max_complexity = max_complexity @max_complexity_count_introspection_fields = count_introspection_fields elsif defined?(@max_complexity) @max_complexity else find_inherited_value(:max_complexity) end end |
.max_depth(new_max_depth = nil, count_introspection_fields: true) ⇒ Object
934 935 936 937 938 939 940 941 942 943 |
# File 'lib/graphql/schema.rb', line 934 def max_depth(new_max_depth = nil, count_introspection_fields: true) if new_max_depth @max_depth = new_max_depth @count_introspection_fields = count_introspection_fields elsif defined?(@max_depth) @max_depth else find_inherited_value(:max_depth) end end |
.null_context ⇒ Object
335 336 337 |
# File 'lib/graphql/schema.rb', line 335 def null_context @null_context || GraphQL::Query::NullContext.instance end |
.use_visibility_profile=(value) ⇒ Object (writeonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
607 608 609 |
# File 'lib/graphql/schema.rb', line 607 def use_visibility_profile=(value) @use_visibility_profile = value end |
.using_backtrace ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1150 1151 1152 |
# File 'lib/graphql/schema.rb', line 1150 def using_backtrace @using_backtrace end |
.validate_max_errors(new_validate_max_errors = NOT_CONFIGURED) ⇒ Object
886 887 888 889 890 891 892 |
# File 'lib/graphql/schema.rb', line 886 def validate_max_errors(new_validate_max_errors = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_validate_max_errors) defined?(@validate_max_errors) ? @validate_max_errors : find_inherited_value(:validate_max_errors) else @validate_max_errors = new_validate_max_errors end end |
.validate_timeout(new_validate_timeout = NOT_CONFIGURED) ⇒ Object
848 849 850 851 852 853 854 855 856 |
# File 'lib/graphql/schema.rb', line 848 def validate_timeout(new_validate_timeout = NOT_CONFIGURED) if !NOT_CONFIGURED.equal?(new_validate_timeout) @validate_timeout = new_validate_timeout elsif defined?(@validate_timeout) @validate_timeout else find_inherited_value(:validate_timeout) || 3 end end |
.visibility ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
609 610 611 |
# File 'lib/graphql/schema.rb', line 609 def visibility @visibility end |
.visibility_profile_class ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
596 597 598 599 600 601 602 603 604 |
# File 'lib/graphql/schema.rb', line 596 def visibility_profile_class if defined?(@visibility_profile_class) @visibility_profile_class elsif superclass.respond_to?(:visibility_profile_class) superclass.visibility_profile_class else GraphQL::Schema::Visibility::Profile end end |
.warden_class ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
582 583 584 585 586 587 588 589 590 |
# File 'lib/graphql/schema.rb', line 582 def warden_class if defined?(@warden_class) @warden_class elsif superclass.respond_to?(:warden_class) superclass.warden_class else GraphQL::Schema::Warden end end |
Class Method Details
.add_subscription_extension_if_necessary ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 |
# File 'lib/graphql/schema.rb', line 1640 def add_subscription_extension_if_necessary # TODO: when there's a proper API for extending root types, migrat this to use it. if !defined?(@subscription_extension_added) && @subscription_object.is_a?(Class) && self.subscriptions @subscription_extension_added = true subscription.all_field_definitions.each do |field| if !field.extensions.any? { |ext| ext.is_a?(Subscriptions::DefaultSubscriptionResolveExtension) } field.extension(Subscriptions::DefaultSubscriptionResolveExtension) end end end end |
.after_any_lazies(maybe_lazies) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return a lazy if any of maybe_lazies are lazy,
otherwise, call the block eagerly and return the result.
1705 1706 1707 1708 1709 1710 1711 1712 1713 |
# File 'lib/graphql/schema.rb', line 1705 def after_any_lazies(maybe_lazies) if maybe_lazies.any? { |l| lazy?(l) } GraphQL::Execution::Lazy.all(maybe_lazies).then do |result| yield result end else yield maybe_lazies end end |
.after_lazy(value, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Call the given block at the right time, either:
- Right away, if value is not registered with lazy_resolve
- After resolving value, if it’s registered with lazy_resolve (eg, Promise)
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 |
# File 'lib/graphql/schema.rb', line 1665 def after_lazy(value, &block) if lazy?(value) GraphQL::Execution::Lazy.new do result = sync_lazy(value) # The returned result might also be lazy, so check it, too after_lazy(result, &block) end else yield(value) if block_given? end end |
.allow_legacy_invalid_empty_selections_on_union(new_value = NOT_CONFIGURED) ⇒ true, ...
This setting controls how GraphQL-Ruby handles empty selections on Union types.
To opt into future, spec-compliant behavior where these selections are rejected, set this to false.
If you need to support previous, non-spec behavior which allowed selecting union fields
but not selecting any fields on that union, set this to true to continue allowing that behavior.
If this is true, then legacy_invalid_empty_selections_on_union_with_type will be called with Query objects
with that kind of selections. You must implement that method
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 |
# File 'lib/graphql/schema.rb', line 1741 def allow_legacy_invalid_empty_selections_on_union(new_value = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_value) if defined?(@allow_legacy_invalid_empty_selections_on_union) @allow_legacy_invalid_empty_selections_on_union else find_inherited_value(:allow_legacy_invalid_empty_selections_on_union) end else @allow_legacy_invalid_empty_selections_on_union = new_value end end |
.allow_legacy_invalid_return_type_conflicts(new_value = NOT_CONFIGURED) ⇒ true, ...
This setting controls how GraphQL-Ruby handles overlapping selections on scalar types when the types don’t match.
When set to false, GraphQL-Ruby will reject those queries with a validation error (as per the GraphQL spec).
When set to true, GraphQL-Ruby will call legacy_invalid_return_type_conflicts when the scenario is encountered.
1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 |
# File 'lib/graphql/schema.rb', line 1793 def allow_legacy_invalid_return_type_conflicts(new_value = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_value) if defined?(@allow_legacy_invalid_return_type_conflicts) @allow_legacy_invalid_return_type_conflicts else find_inherited_value(:allow_legacy_invalid_return_type_conflicts) end else @allow_legacy_invalid_return_type_conflicts = new_value end end |
.as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false) ⇒ Hash
Return the Hash response of Introspection::INTROSPECTION_QUERY.
269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/graphql/schema.rb', line 269 def as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false) introspection_query = Introspection.query( include_deprecated_args: include_deprecated_args, include_schema_description: include_schema_description, include_is_repeatable: include_is_repeatable, include_is_one_of: include_is_one_of, include_specified_by_url: include_specified_by_url, ) execute(introspection_query, context: context).to_h end |
.build_trace_mode(mode) ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/graphql/schema.rb', line 212 def build_trace_mode(mode) case mode when :default # Use the superclass's default mode if it has one, or else start an inheritance chain at the built-in base class. base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode, build: true)) || GraphQL::Tracing::Trace const_set(:DefaultTrace, Class.new(base_class) do include DefaultTraceClass end) else # First, see if the superclass has a custom-defined class for this. # Then, if it doesn't, use this class's default trace base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || trace_class_for(:default, build: true) # Prepare the default trace class if it hasn't been initialized yet base_class ||= (own_trace_modes[:default] = build_trace_mode(:default)) mods = trace_modules_for(mode) if base_class < DefaultTraceClass mods = trace_modules_for(:default) + mods end # Copy the existing default options into this mode's options = (:default) (mode, ) Class.new(base_class) do !mods.empty? && include(*mods) end end end |
.complexity_cost_calculation_mode(new_mode = NOT_CONFIGURED) ⇒ Object
The legacy complexity implementation included several bugs:
- In some cases, it used the lexically last field to determine a cost, instead of calculating the maximum among selections
- In some cases, it called field complexity hooks repeatedly (when it should have only called them once)
The future implementation may produce higher total complexity scores, so it’s not active by default yet. You can opt into
the future default behavior by configuring :future here. Or, you can choose a mode for each query with complexity_cost_calculation_mode_for.
The legacy mode is currently maintained alongside the future one, but it will be removed in a future GraphQL-Ruby version.
If you choose :compare, you must also implement legacy_complexity_cost_calculation_mismatch to handle the input somehow.
1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 |
# File 'lib/graphql/schema.rb', line 1845 def complexity_cost_calculation_mode(new_mode = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_mode) if defined?(@complexity_cost_calculation_mode) @complexity_cost_calculation_mode else find_inherited_value(:complexity_cost_calculation_mode) end else @complexity_cost_calculation_mode = new_mode end end |
.complexity_cost_calculation_mode_for(multiplex_context) ⇒ :future, ...
Implement this method to produce a per-query complexity cost calculation mode. (Technically, it’s per-multiplex.)
This is a way to check the compatibility of queries coming to your API without adding overhead of running :compare
for every query. You could sample traffic, turn it off/on with feature flags, or anything else.
1887 1888 1889 |
# File 'lib/graphql/schema.rb', line 1887 def complexity_cost_calculation_mode_for(multiplex_context) complexity_cost_calculation_mode end |
.context_class(new_context_class = nil) ⇒ Object
1104 1105 1106 1107 1108 1109 1110 |
# File 'lib/graphql/schema.rb', line 1104 def context_class(new_context_class = nil) if new_context_class @context_class = new_context_class else @context_class || find_inherited_value(:context_class, GraphQL::Query::Context) end end |
.count_introspection_fields ⇒ Object
945 946 947 948 949 950 951 |
# File 'lib/graphql/schema.rb', line 945 def count_introspection_fields if defined?(@count_introspection_fields) @count_introspection_fields else find_inherited_value(:count_introspection_fields, true) end end |
.cursor_encoder(new_encoder = nil) ⇒ Object
776 777 778 779 780 781 |
# File 'lib/graphql/schema.rb', line 776 def cursor_encoder(new_encoder = nil) if new_encoder @cursor_encoder = new_encoder end @cursor_encoder || find_inherited_value(:cursor_encoder, Base64Encoder) end |
.default_analysis_engine ⇒ Object
1061 1062 1063 1064 1065 1066 1067 |
# File 'lib/graphql/schema.rb', line 1061 def default_analysis_engine if superclass <= GraphQL::Schema superclass.default_analysis_engine else @default_analysis_engine ||= GraphQL::Analysis::AST end end |
.default_directives ⇒ Object
1419 1420 1421 1422 1423 1424 1425 1426 1427 |
# File 'lib/graphql/schema.rb', line 1419 def default_directives @default_directives ||= { "include" => GraphQL::Schema::Directive::Include, "skip" => GraphQL::Schema::Directive::Skip, "deprecated" => GraphQL::Schema::Directive::Deprecated, "oneOf" => GraphQL::Schema::Directive::OneOf, "specifiedBy" => GraphQL::Schema::Directive::SpecifiedBy, }.freeze end |
.default_execution_strategy ⇒ Object
1053 1054 1055 1056 1057 1058 1059 |
# File 'lib/graphql/schema.rb', line 1053 def default_execution_strategy if superclass <= GraphQL::Schema superclass.default_execution_strategy else @default_execution_strategy ||= GraphQL::Execution::Interpreter end end |
.default_logger(new_default_logger = NOT_CONFIGURED) ⇒ Object
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
# File 'lib/graphql/schema.rb', line 1071 def default_logger(new_default_logger = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_default_logger) if defined?(@default_logger) @default_logger elsif superclass.respond_to?(:default_logger) superclass.default_logger elsif defined?(Rails) && Rails.respond_to?(:logger) && (rails_logger = Rails.logger) rails_logger else def_logger = Logger.new($stdout) def_logger.info! # It doesn't output debug info by default def_logger end elsif new_default_logger == nil @default_logger = Logger.new(IO::NULL) else @default_logger = new_default_logger end end |
.default_max_page_size(new_default_max_page_size = nil) ⇒ Object
783 784 785 786 787 788 789 |
# File 'lib/graphql/schema.rb', line 783 def default_max_page_size(new_default_max_page_size = nil) if new_default_max_page_size @default_max_page_size = new_default_max_page_size else @default_max_page_size || find_inherited_value(:default_max_page_size) end end |
.default_page_size(new_default_page_size = nil) ⇒ Object
802 803 804 805 806 807 808 |
# File 'lib/graphql/schema.rb', line 802 def default_page_size(new_default_page_size = nil) if new_default_page_size @default_page_size = new_default_page_size else @default_page_size || find_inherited_value(:default_page_size) end end |
.default_trace_mode(new_mode = NOT_CONFIGURED) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/graphql/schema.rb', line 152 def default_trace_mode(new_mode = NOT_CONFIGURED) if !NOT_CONFIGURED.equal?(new_mode) @default_trace_mode = new_mode elsif defined?(@default_trace_mode) && !@default_trace_mode.nil? # This `nil?` check seems necessary because of # Ractors silently initializing @default_trace_mode somehow @default_trace_mode elsif superclass.respond_to?(:default_trace_mode) superclass.default_trace_mode else :default end end |
.deprecated_graphql_definition ⇒ Object
138 139 140 |
# File 'lib/graphql/schema.rb', line 138 def deprecated_graphql_definition graphql_definition(silence_deprecation_warning: true) end |
.description(new_description = nil) ⇒ String?
295 296 297 298 299 300 301 302 303 |
# File 'lib/graphql/schema.rb', line 295 def description(new_description = nil) if new_description @description = new_description elsif defined?(@description) @description else find_inherited_value(:description, nil) end end |
.detailed_trace?(query) ⇒ Boolean
Returns When true, save a detailed trace for this query.
1435 1436 1437 |
# File 'lib/graphql/schema.rb', line 1435 def detailed_trace?(query) raise "#{self} must implement `def.detailed_trace?(query)` to use DetailedTrace. Implement this method in your schema definition." end |
.did_you_mean(new_dym = NOT_CONFIGURED) ⇒ Object
Returns DidYouMean if it’s defined.
Override this to return nil if you don’t want to use DidYouMean
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 |
# File 'lib/graphql/schema.rb', line 1717 def did_you_mean(new_dym = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_dym) if defined?(@did_you_mean) @did_you_mean else find_inherited_value(:did_you_mean, defined?(DidYouMean) ? DidYouMean : nil) end else @did_you_mean = new_dym end end |
.directive(new_directive) ⇒ Object
Attach a single directive to this schema
1411 1412 1413 1414 1415 1416 1417 |
# File 'lib/graphql/schema.rb', line 1411 def directive(new_directive) if use_visibility_profile? own_directives[new_directive.graphql_name] = new_directive else add_type_and_traverse(new_directive, root: false) end end |
.directives(*new_directives) ⇒ Object
Add several directives at once
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 |
# File 'lib/graphql/schema.rb', line 1395 def directives(*new_directives) if !new_directives.empty? new_directives.flatten.each { |d| directive(d) } end inherited_dirs = find_inherited_value(:directives, default_directives) if !own_directives.empty? inherited_dirs.merge(own_directives) else inherited_dirs end end |
.disable_introspection_entry_points ⇒ Object
953 954 955 956 957 |
# File 'lib/graphql/schema.rb', line 953 def disable_introspection_entry_points @disable_introspection_entry_points = true # TODO: this clears the cache made in `def types`. But this is not a great solution. @introspection_system = nil end |
.disable_introspection_entry_points? ⇒ Boolean
971 972 973 974 975 976 977 |
# File 'lib/graphql/schema.rb', line 971 def disable_introspection_entry_points? if instance_variable_defined?(:@disable_introspection_entry_points) @disable_introspection_entry_points else find_inherited_value(:disable_introspection_entry_points?, false) end end |
.disable_schema_introspection_entry_point ⇒ Object
959 960 961 962 963 |
# File 'lib/graphql/schema.rb', line 959 def disable_schema_introspection_entry_point @disable_schema_introspection_entry_point = true # TODO: this clears the cache made in `def types`. But this is not a great solution. @introspection_system = nil end |
.disable_schema_introspection_entry_point? ⇒ Boolean
979 980 981 982 983 984 985 |
# File 'lib/graphql/schema.rb', line 979 def disable_schema_introspection_entry_point? if instance_variable_defined?(:@disable_schema_introspection_entry_point) @disable_schema_introspection_entry_point else find_inherited_value(:disable_schema_introspection_entry_point?, false) end end |
.disable_type_introspection_entry_point ⇒ Object
965 966 967 968 969 |
# File 'lib/graphql/schema.rb', line 965 def disable_type_introspection_entry_point @disable_type_introspection_entry_point = true # TODO: this clears the cache made in `def types`. But this is not a great solution. @introspection_system = nil end |
.disable_type_introspection_entry_point? ⇒ Boolean
987 988 989 990 991 992 993 |
# File 'lib/graphql/schema.rb', line 987 def disable_type_introspection_entry_point? if instance_variable_defined?(:@disable_type_introspection_entry_point) @disable_type_introspection_entry_point else find_inherited_value(:disable_type_introspection_entry_point?, false) end end |
.error_handlers ⇒ Object
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 |
# File 'lib/graphql/schema.rb', line 1132 def error_handlers @error_handlers ||= begin new_handler_hash = ->(h, k) { h[k] = { class: k, handler: nil, subclass_handlers: Hash.new(&new_handler_hash), } } { class: nil, handler: nil, subclass_handlers: Hash.new(&new_handler_hash), } end end |
.execute(query_str = nil, **kwargs) ⇒ GraphQL::Query::Result
Execute a query on itself.
1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 |
# File 'lib/graphql/schema.rb', line 1587 def execute(query_str = nil, **kwargs) if query_str kwargs[:query] = query_str end # Some of the query context _should_ be passed to the multiplex, too multiplex_context = if (ctx = kwargs[:context]) { backtrace: ctx[:backtrace], tracers: ctx[:tracers], trace: ctx[:trace], dataloader: ctx[:dataloader], trace_mode: ctx[:trace_mode], } else {} end # Since we're running one query, don't run a multiplex-level complexity analyzer all_results = multiplex([kwargs], max_complexity: nil, context: multiplex_context) all_results[0] end |
.extra_types(*new_extra_types) ⇒ Array<Module>
Returns Type definitions added to this schema.
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 |
# File 'lib/graphql/schema.rb', line 997 def extra_types(*new_extra_types) if !new_extra_types.empty? new_extra_types = new_extra_types.flatten @own_extra_types ||= [] @own_extra_types.concat(new_extra_types) end inherited_et = find_inherited_value(:extra_types, nil) if inherited_et if @own_extra_types inherited_et + @own_extra_types else inherited_et end else @own_extra_types || EMPTY_ARRAY end end |
.find(path) ⇒ Object
305 306 307 308 309 310 311 |
# File 'lib/graphql/schema.rb', line 305 def find(path) if !@finder @find_cache = {} @finder ||= GraphQL::Schema::Finder.new(self) end @find_cache[path] ||= @finder.find(path) end |
.from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {}, base_types: {}) ⇒ Class
Create schema from an IDL schema or file containing an IDL definition.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/graphql/schema.rb', line 115 def from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {}, base_types: {}) # If the file ends in `.graphql` or `.graphqls`, treat it like a filepath if definition_or_path.end_with?(".graphql") || definition_or_path.end_with?(".graphqls") GraphQL::Schema::BuildFromDefinition.from_definition_path( self, definition_or_path, default_resolve: default_resolve, parser: parser, using: using, base_types: base_types, ) else GraphQL::Schema::BuildFromDefinition.from_definition( self, definition_or_path, default_resolve: default_resolve, parser: parser, using: using, base_types: base_types, ) end end |
.from_introspection(introspection_result) ⇒ Class<GraphQL::Schema>
Create schema with the result of an introspection query.
105 106 107 |
# File 'lib/graphql/schema.rb', line 105 def from_introspection(introspection_result) GraphQL::Schema::Loader.load(introspection_result) end |
.get_field(type_or_name, field_name, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Object
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 |
# File 'lib/graphql/schema.rb', line 710 def get_field(type_or_name, field_name, context = null_context, use_visibility_profile = use_visibility_profile?) if use_visibility_profile profile = Visibility::Profile.from_context(context, self) parent_type = case type_or_name when String profile.type(type_or_name) when Module type_or_name when LateBoundType profile.type(type_or_name.name) else raise GraphQL::InvariantError, "Unexpected field owner for #{field_name.inspect}: #{type_or_name.inspect} (#{type_or_name.class})" end return profile.field(parent_type, field_name) end parent_type = case type_or_name when LateBoundType get_type(type_or_name.name, context) when String get_type(type_or_name, context) when Module type_or_name else raise GraphQL::InvariantError, "Unexpected field owner for #{field_name.inspect}: #{type_or_name.inspect} (#{type_or_name.class})" end if parent_type.kind.fields? && (field = parent_type.get_field(field_name, context)) field elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name)) entry_point_field elsif (dynamic_field = introspection_system.dynamic_field(name: field_name)) dynamic_field else nil end end |
.get_fields(type, context = null_context) ⇒ Object
747 748 749 |
# File 'lib/graphql/schema.rb', line 747 def get_fields(type, context = null_context) type.fields(context) end |
.get_type(type_name, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Module?
Returns A type, or nil if there’s no type called type_name.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/graphql/schema.rb', line 375 def get_type(type_name, context = null_context, use_visibility_profile = use_visibility_profile?) if use_visibility_profile profile = Visibility::Profile.from_context(context, self) return profile.type(type_name) end local_entry = own_types[type_name] type_defn = case local_entry when nil nil when Array if context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile) local_entry else visible_t = nil warden = Warden.from_context(context) local_entry.each do |t| if warden.visible_type?(t, context) if visible_t.nil? visible_t = t else raise DuplicateNamesError.new( duplicated_name: type_name, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect ) end end end visible_t end when Module local_entry else raise "Invariant: unexpected own_types[#{type_name.inspect}]: #{local_entry.inspect}" end type_defn || introspection_system.types[type_name] || # todo context-specific introspection? (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context, use_visibility_profile) : nil) end |
.handle_or_reraise(context, err) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 |
# File 'lib/graphql/schema.rb', line 1153 def handle_or_reraise(context, err) handler = Execution::Errors.find_handler_for(self, err.class) if handler obj = context[:current_object] args = context[:current_arguments] args = args && args.respond_to?(:keyword_arguments) ? args.keyword_arguments : nil field = context[:current_field] if obj.is_a?(GraphQL::Schema::Object) obj = obj.object end handler[:handler].call(err, obj, args, context, field) else if (context[:backtrace] || using_backtrace) && !err.is_a?(GraphQL::ExecutionError) err = GraphQL::Backtrace::TracedError.new(err, context) end raise err end end |
.has_defined_type?(type_name) ⇒ Boolean
Returns Does this schema have any definition for a type named type_name, regardless of visibility?.
415 416 417 |
# File 'lib/graphql/schema.rb', line 415 def has_defined_type?(type_name) own_types.key?(type_name) || introspection_system.types.key?(type_name) || (superclass.respond_to?(:has_defined_type?) ? superclass.has_defined_type?(type_name) : false) end |
.id_from_object(application_object, graphql_type, context) ⇒ String
Return a stable ID string for object so that it can be refetched later, using object_from_id.
1270 1271 1272 |
# File 'lib/graphql/schema.rb', line 1270 def id_from_object(application_object, graphql_type, context) raise GraphQL::RequiredImplementationMissingError, "#{self.name}.id_from_object(application_object, graphql_type, context) must be implemented to create global ids (tried to create an id for `#{application_object.inspect}`)" end |
.inherited(child_class) ⇒ Object
rubocop:enable Lint/DuplicateMethods
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 |
# File 'lib/graphql/schema.rb', line 1221 def inherited(child_class) if self == GraphQL::Schema child_class.directives(default_directives.values) child_class.extend(SubclassGetReferencesTo) end # Make sure the child class has these built out, so that # subclasses can be modified by later calls to `trace_with` own_trace_modes.each do |name, _class| child_class.own_trace_modes[name] = child_class.build_trace_mode(name) end child_class.singleton_class.prepend(ResolveTypeWithType) if use_visibility_profile? vis = self.visibility child_class.visibility = vis.dup_for(child_class) end child_class.null_context = Query::NullContext.new(schema: child_class) super end |
.instrument(instrument_step, instrumenter, options = {}) ⇒ Object
1383 1384 1385 1386 1387 1388 1389 1390 1391 |
# File 'lib/graphql/schema.rb', line 1383 def instrument(instrument_step, instrumenter, = {}) warn <<~WARN Schema.instrument is deprecated, use `trace_with` instead: https://graphql-ruby.org/queries/tracing.html" (From `#{self}.instrument(#{instrument_step}, #{instrumenter})` at #{caller(1, 1).first}) WARN trace_with(Tracing::LegacyHooksTrace) own_instrumenters[instrument_step] << instrumenter end |
.instrumenters ⇒ Object
1632 1633 1634 1635 1636 1637 |
# File 'lib/graphql/schema.rb', line 1632 def instrumenters inherited_instrumenters = find_inherited_value(:instrumenters) || Hash.new { |h,k| h[k] = [] } inherited_instrumenters.merge(own_instrumenters) do |_step, inherited, own| inherited + own end end |
.introspection(new_introspection_namespace = nil) ⇒ Module?
Pass a custom introspection module here to use it for this schema.
754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/graphql/schema.rb', line 754 def introspection(new_introspection_namespace = nil) if new_introspection_namespace @introspection = new_introspection_namespace # reset this cached value: @introspection_system = nil introspection_system @introspection else @introspection || find_inherited_value(:introspection) end end |
.introspection_system ⇒ Schema::IntrospectionSystem
Returns Based on introspection.
767 768 769 770 771 772 773 774 |
# File 'lib/graphql/schema.rb', line 767 def introspection_system if !@introspection_system @introspection_system = Schema::IntrospectionSystem.new(self) @introspection_system.resolve_late_bindings self.visibility&.introspection_system_configured(@introspection_system) end @introspection_system end |
.lazy?(obj) ⇒ Boolean
Returns True if this object should be lazily resolved.
1697 1698 1699 |
# File 'lib/graphql/schema.rb', line 1697 def lazy?(obj) !!lazy_method_name(obj) end |
.lazy_method_name(obj) ⇒ Symbol?
Returns The method name to lazily resolve obj, or nil if obj’s class wasn’t registered with lazy_resolve.
1692 1693 1694 |
# File 'lib/graphql/schema.rb', line 1692 def lazy_method_name(obj) lazy_methods.get(obj) end |
.lazy_resolve(lazy_class, value_method) ⇒ Object
1361 1362 1363 |
# File 'lib/graphql/schema.rb', line 1361 def lazy_resolve(lazy_class, value_method) lazy_methods.set(lazy_class, value_method) end |
.legacy_complexity_cost_calculation_mismatch(multiplex, future_complexity_cost, legacy_complexity_cost) ⇒ Integer
Implement this method in your schema to handle mismatches when :compare is used.
1906 1907 1908 |
# File 'lib/graphql/schema.rb', line 1906 def legacy_complexity_cost_calculation_mismatch(multiplex, future_complexity_cost, legacy_complexity_cost) raise "Implement #{self}.legacy_complexity_cost(multiplex, future_complexity_cost, legacy_complexity_cost) to handle this mismatch (#{future_complexity_cost} vs. #{legacy_complexity_cost}) and return a value to use" end |
.legacy_invalid_empty_selections_on_union(query) ⇒ :return_validation_error, ...
This method is called during validation when a previously-allowed, but non-spec query is encountered where a union field has no child selections on it.
If legacy_invalid_empty_selections_on_union_with_type is overridden, this method will not be called.
You should implement this method or legacy_invalid_empty_selections_on_union_with_type
to log the violation so that you can contact clients and notify them about changing their queries.
Then return a suitable value to tell GraphQL-Ruby how to continue.
1765 1766 1767 |
# File 'lib/graphql/schema.rb', line 1765 def legacy_invalid_empty_selections_on_union(query) raise "Implement `def self.legacy_invalid_empty_selections_on_union_with_type(query, type)` or `def self.legacy_invalid_empty_selections_on_union(query)` to handle this scenario" end |
.legacy_invalid_empty_selections_on_union_with_type(query, type) ⇒ :return_validation_error, ...
This method is called during validation when a previously-allowed, but non-spec query is encountered where a union field has no child selections on it.
You should implement this method to log the violation so that you can contact clients and notify them about changing their queries. Then return a suitable value to tell GraphQL-Ruby how to continue.
1780 1781 1782 |
# File 'lib/graphql/schema.rb', line 1780 def legacy_invalid_empty_selections_on_union_with_type(query, type) legacy_invalid_empty_selections_on_union(query) end |
.legacy_invalid_return_type_conflicts(query, type1, type2, node1, node2) ⇒ :return_validation_error, ...
This method is called when the query contains fields which don’t contain matching scalar types. This was previously allowed by GraphQL-Ruby but it’s a violation of the GraphQL spec.
You should implement this method to log the violation so that you observe usage of these fields. Fixing this scenario might mean adding new fields, and telling clients to use those fields. (Changing the field return type would be a breaking change, but if it works for your client use cases, that might work, too.)
1821 1822 1823 |
# File 'lib/graphql/schema.rb', line 1821 def legacy_invalid_return_type_conflicts(query, type1, type2, node1, node2) raise "Implement #{self}.legacy_invalid_return_type_conflicts to handle this invalid selection" end |
.load_type(type_name, ctx) ⇒ Object
Called when a type is needed by name at runtime
1288 1289 1290 |
# File 'lib/graphql/schema.rb', line 1288 def load_type(type_name, ctx) get_type(type_name, ctx) end |
.logger_for(context) ⇒ Logger
Returns A logger to use for this context configuration, falling back to default_logger.
1093 1094 1095 1096 1097 1098 1099 1100 1101 |
# File 'lib/graphql/schema.rb', line 1093 def logger_for(context) if context && context[:logger] == false Logger.new(IO::NULL) elsif context && (l = context[:logger]) l else default_logger end end |
.max_complexity_count_introspection_fields ⇒ Object
907 908 909 910 911 912 913 |
# File 'lib/graphql/schema.rb', line 907 def max_complexity_count_introspection_fields if defined?(@max_complexity_count_introspection_fields) @max_complexity_count_introspection_fields else find_inherited_value(:max_complexity_count_introspection_fields, true) end end |
.max_query_string_tokens(new_max_tokens = NOT_CONFIGURED) ⇒ nil, Integer
A limit on the number of tokens to accept on incoming query strings. Use this to prevent parsing maliciously-large query strings.
794 795 796 797 798 799 800 |
# File 'lib/graphql/schema.rb', line 794 def max_query_string_tokens(new_max_tokens = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_max_tokens) defined?(@max_query_string_tokens) ? @max_query_string_tokens : find_inherited_value(:max_query_string_tokens) else @max_query_string_tokens = new_max_tokens end end |
.multiplex(queries, **kwargs) ⇒ Array<GraphQL::Query::Result>
Execute several queries on itself, concurrently.
1628 1629 1630 |
# File 'lib/graphql/schema.rb', line 1628 def multiplex(queries, **kwargs) GraphQL::Execution::Interpreter.run_all(self, queries, **kwargs) end |
.multiplex_analyzer(new_analyzer) ⇒ Object
1568 1569 1570 |
# File 'lib/graphql/schema.rb', line 1568 def multiplex_analyzer(new_analyzer) own_multiplex_analyzers << new_analyzer end |
.multiplex_analyzers ⇒ Object
1572 1573 1574 |
# File 'lib/graphql/schema.rb', line 1572 def multiplex_analyzers find_inherited_value(:multiplex_analyzers, EMPTY_ARRAY) + own_multiplex_analyzers end |
.mutation(new_mutation_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root mutation { ... } object for this schema.
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/graphql/schema.rb', line 485 def mutation(new_mutation_object = nil, &lazy_load_block) if new_mutation_object || block_given? if @mutation_object dup_defn = new_mutation_object || yield raise GraphQL::Error, "Second definition of `mutation(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@mutation_object.inspect}" elsif use_visibility_profile? if block_given? if visibility.preload? @mutation_object = lazy_load_block.call self.visibility.mutation_configured(@mutation_object) else @mutation_object = lazy_load_block end else @mutation_object = new_mutation_object self.visibility.mutation_configured(@mutation_object) end else @mutation_object = new_mutation_object || lazy_load_block.call add_type_and_traverse(@mutation_object, root: true) end nil elsif @mutation_object.is_a?(Proc) @mutation_object = @mutation_object.call self.visibility&.mutation_configured(@mutation_object) @mutation_object else @mutation_object || find_inherited_value(:mutation) end end |
.mutation_execution_strategy(new_mutation_execution_strategy = nil, deprecation_warning: true) ⇒ Object
822 823 824 825 826 827 828 829 830 831 832 |
# File 'lib/graphql/schema.rb', line 822 def mutation_execution_strategy(new_mutation_execution_strategy = nil, deprecation_warning: true) if deprecation_warning warn "GraphQL::Schema.mutation_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead." warn " #{caller(1, 1).first}" end if new_mutation_execution_strategy @mutation_execution_strategy = new_mutation_execution_strategy else @mutation_execution_strategy || (superclass.respond_to?(:mutation_execution_strategy) ? superclass.mutation_execution_strategy(deprecation_warning: false) : self.default_execution_strategy) end end |
.new_trace(mode: nil, **options) ⇒ Tracing::Trace
Create a trace instance which will include the trace modules specified for the optional mode.
If no mode: is given, then default_trace_mode will be used.
If this schema is using Tracing::DetailedTrace and detailed_trace? returns true, then
DetailedTrace’s mode will override the passed-in mode.
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 |
# File 'lib/graphql/schema.rb', line 1527 def new_trace(mode: nil, **) should_sample = if detailed_trace if (query = [:query]) detailed_trace?(query) elsif (multiplex = [:multiplex]) if multiplex.queries.length == 1 detailed_trace?(multiplex.queries.first) else detailed_trace?(multiplex) end end else false end if should_sample mode = detailed_trace.trace_mode else target = [:query] || [:multiplex] mode ||= target && target.context[:trace_mode] end trace_mode = mode || default_trace_mode = (trace_mode) = .merge() trace_class_for_mode = trace_class_for(trace_mode, build: true) trace_class_for_mode.new(**) end |
.object_from_id(object_id, context) ⇒ Object?
Fetch an object based on an incoming ID and the current context. This method should return an object
from your application, or return nil if there is no object or the object shouldn’t be available to this operation.
1253 1254 1255 |
# File 'lib/graphql/schema.rb', line 1253 def object_from_id(object_id, context) raise GraphQL::RequiredImplementationMissingError, "#{self.name}.object_from_id(object_id, context) must be implemented to load by ID (tried to load from id `#{object_id}`)" end |
.orphan_types(*new_orphan_types) ⇒ Array<Class<GraphQL::Schema::Object>>
Tell the schema about these types so that they can be registered as implementations of interfaces in the schema.
This method must be used when an object type is connected to the schema as an interface implementor but not as a return type of a field. In that case, if the object type isn’t registered here, GraphQL-Ruby won’t be able to find it.
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 |
# File 'lib/graphql/schema.rb', line 1022 def orphan_types(*new_orphan_types) if !new_orphan_types.empty? new_orphan_types = new_orphan_types.flatten non_object_types = new_orphan_types.reject { |ot| ot.is_a?(Class) && ot < GraphQL::Schema::Object } if !non_object_types.empty? raise ArgumentError, <<~ERR Only object type classes should be added as `orphan_types(...)`. - Remove these no-op types from `orphan_types`: #{non_object_types.map { |t| "#{t.inspect} (#{t.kind.name})"}.join(", ")} - See https://graphql-ruby.org/type_definitions/interfaces.html#orphan-types To add other types to your schema, you might want `extra_types`: https://graphql-ruby.org/schema/definition.html#extra-types ERR end add_type_and_traverse(new_orphan_types, root: false) unless use_visibility_profile? own_orphan_types.concat(new_orphan_types.flatten) self.visibility&.orphan_types_configured(new_orphan_types) end inherited_ot = find_inherited_value(:orphan_types, nil) if inherited_ot if !own_orphan_types.empty? inherited_ot + own_orphan_types else inherited_ot end else own_orphan_types end end |
.own_trace_modes ⇒ Object
208 209 210 |
# File 'lib/graphql/schema.rb', line 208 def own_trace_modes @own_trace_modes ||= {} end |
.own_trace_modules ⇒ Object
240 241 242 |
# File 'lib/graphql/schema.rb', line 240 def own_trace_modules @own_trace_modules ||= Hash.new { |h, k| h[k] = [] } end |
.parse_error(parse_err, ctx) ⇒ Object
A function to call when execute receives an invalid query string
The default is to add the error to context.errors
1357 1358 1359 |
# File 'lib/graphql/schema.rb', line 1357 def parse_error(parse_err, ctx) ctx.errors.push(parse_err) end |
.plugins ⇒ Object
329 330 331 |
# File 'lib/graphql/schema.rb', line 329 def plugins find_inherited_value(:plugins, EMPTY_ARRAY) + own_plugins end |
.possible_types(type = nil, context = null_context, use_visibility_profile = use_visibility_profile?) ) ⇒ Hash<String, Module>, Array<Module>
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
# File 'lib/graphql/schema.rb', line 626 def possible_types(type = nil, context = null_context, use_visibility_profile = use_visibility_profile?) if use_visibility_profile if type return Visibility::Profile.from_context(context, self).possible_types(type) else raise "Schema.possible_types is not implemented for `use_visibility_profile?`" end end if type # TODO duck-typing `.possible_types` would probably be nicer here if type.kind.union? type.possible_types(context: context) else stored_possible_types = own_possible_types[type] visible_possible_types = if stored_possible_types && type.kind.interface? stored_possible_types.select do |possible_type| possible_type.interfaces(context).include?(type) end else stored_possible_types end visible_possible_types || introspection_system.possible_types[type] || ( superclass.respond_to?(:possible_types) ? superclass.possible_types(type, context, use_visibility_profile) : EMPTY_ARRAY ) end else find_inherited_value(:possible_types, EMPTY_HASH) .merge(own_possible_types) .merge(introspection_system.possible_types) end end |
.query(new_query_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root query { ... } object for this schema.
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
# File 'lib/graphql/schema.rb', line 446 def query(new_query_object = nil, &lazy_load_block) if new_query_object || block_given? if @query_object dup_defn = new_query_object || yield raise GraphQL::Error, "Second definition of `query(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@query_object.inspect}" elsif use_visibility_profile? if block_given? if visibility.preload? @query_object = lazy_load_block.call self.visibility.query_configured(@query_object) else @query_object = lazy_load_block end else @query_object = new_query_object self.visibility.query_configured(@query_object) end else @query_object = new_query_object || lazy_load_block.call add_type_and_traverse(@query_object, root: true) end nil elsif @query_object.is_a?(Proc) @query_object = @query_object.call self.visibility&.query_configured(@query_object) @query_object else @query_object || find_inherited_value(:query) end end |
.query_analyzer(new_analyzer) ⇒ Object
1558 1559 1560 |
# File 'lib/graphql/schema.rb', line 1558 def query_analyzer(new_analyzer) own_query_analyzers << new_analyzer end |
.query_analyzers ⇒ Object
1562 1563 1564 |
# File 'lib/graphql/schema.rb', line 1562 def query_analyzers find_inherited_value(:query_analyzers, EMPTY_ARRAY) + own_query_analyzers end |
.query_class(new_query_class = NOT_CONFIGURED) ⇒ Object
876 877 878 879 880 881 882 |
# File 'lib/graphql/schema.rb', line 876 def query_class(new_query_class = NOT_CONFIGURED) if NOT_CONFIGURED.equal?(new_query_class) @query_class || (superclass.respond_to?(:query_class) ? superclass.query_class : GraphQL::Query) else @query_class = new_query_class end end |
.query_execution_strategy(new_query_execution_strategy = nil, deprecation_warning: true) ⇒ Object
810 811 812 813 814 815 816 817 818 819 820 |
# File 'lib/graphql/schema.rb', line 810 def query_execution_strategy(new_query_execution_strategy = nil, deprecation_warning: true) if deprecation_warning warn "GraphQL::Schema.query_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead." warn " #{caller(1, 1).first}" end if new_query_execution_strategy @query_execution_strategy = new_query_execution_strategy else @query_execution_strategy || (superclass.respond_to?(:query_execution_strategy) ? superclass.query_execution_strategy(deprecation_warning: false) : self.default_execution_strategy) end end |
.query_stack_error(query, err) ⇒ void
This method returns an undefined value.
Called when execution encounters a SystemStackError. By default, it adds a client-facing error to the response.
You could modify this method to report this error to your bug tracker.
1657 1658 1659 |
# File 'lib/graphql/schema.rb', line 1657 def query_stack_error(query, err) query.context.errors.push(GraphQL::ExecutionError.new("This query is too large to execute.")) end |
.references_to(to_type = nil, from: nil) ⇒ Object
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
# File 'lib/graphql/schema.rb', line 685 def references_to(to_type = nil, from: nil) if to_type if from refs = own_references_to[to_type] ||= [] refs << from else get_references_to(to_type) || EMPTY_ARRAY end else # `@own_references_to` can be quite large for big schemas, # and generally speaking, we won't inherit any values. # So optimize the most common case -- don't create a duplicate Hash. inherited_value = find_inherited_value(:references_to, EMPTY_HASH) if !inherited_value.empty? inherited_value.merge(own_references_to) else own_references_to end end end |
.rescue_from(*err_classes, &handler_block) {|error, object, arguments, context| ... } ⇒ Object
Register a handler for errors raised during execution. The handlers can return a new value or raise a new error.
1126 1127 1128 1129 1130 |
# File 'lib/graphql/schema.rb', line 1126 def rescue_from(*err_classes, &handler_block) err_classes.each do |err_class| Execution::Errors.register_rescue_from(err_class, error_handlers[:subclass_handlers], handler_block) end end |
.resolve_type(abstract_type, application_object, context) ⇒ Class<GraphQL::Schema::Object] The Object type definition to use for `obj`
GraphQL-Ruby calls this method during execution when it needs the application to determine the type to use for an object.
Usually, this object was returned from a field whose return type is an Interface or a Union. But this method is called in other cases, too – for example, when GraphQL::Schema::Argument#loads cases an object to be directly loaded from the database.
1216 1217 1218 |
# File 'lib/graphql/schema.rb', line 1216 def resolve_type(abstract_type, application_object, context) raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(abstract_type, application_object, context) must be implemented to use Union types, Interface types, `loads:`, or `run_partials` (tried to resolve: #{abstract_type.name})" end |
.resolves_lazies? ⇒ Boolean
1373 1374 1375 1376 1377 1378 1379 1380 1381 |
# File 'lib/graphql/schema.rb', line 1373 def resolves_lazies? lazy_method_count = 0 lazy_methods.each do |k, v| if !v.nil? lazy_method_count += 1 end end lazy_method_count > 2 end |
.root_type_for_operation(operation) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
559 560 561 562 563 564 565 566 567 568 569 570 |
# File 'lib/graphql/schema.rb', line 559 def root_type_for_operation(operation) case operation when "query" query when "mutation" mutation when "subscription" subscription else raise ArgumentError, "unknown operation type: #{operation}" end end |
.root_types ⇒ Array<Class>
Returns The root types (query, mutation, subscription) defined for this schema.
573 574 575 576 577 578 579 |
# File 'lib/graphql/schema.rb', line 573 def root_types if use_visibility_profile? [query, mutation, subscription].compact else @root_types end end |
.sanitized_printer(new_sanitized_printer = nil) ⇒ Object
1576 1577 1578 1579 1580 1581 1582 |
# File 'lib/graphql/schema.rb', line 1576 def sanitized_printer(new_sanitized_printer = nil) if new_sanitized_printer @own_sanitized_printer = new_sanitized_printer else @own_sanitized_printer || GraphQL::Language::SanitizedPrinter end end |
.schema_directive(dir_class, **options) ⇒ Object
1278 1279 1280 1281 |
# File 'lib/graphql/schema.rb', line 1278 def schema_directive(dir_class, **) @own_schema_directives ||= [] Member::HasDirectives.add_directive(self, @own_schema_directives, dir_class, ) end |
.schema_directives ⇒ Object
1283 1284 1285 |
# File 'lib/graphql/schema.rb', line 1283 def schema_directives Member::HasDirectives.get_directives(self, @own_schema_directives, :schema_directives) end |
.static_validator ⇒ Object
313 314 315 |
# File 'lib/graphql/schema.rb', line 313 def static_validator GraphQL::StaticValidation::Validator.new(schema: self) end |
.subscription(new_subscription_object = nil, &lazy_load_block) ⇒ Class<GraphQL::Schema::Object>?
Get or set the root subscription { ... } object for this schema.
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 |
# File 'lib/graphql/schema.rb', line 524 def subscription(new_subscription_object = nil, &lazy_load_block) if new_subscription_object || block_given? if @subscription_object dup_defn = new_subscription_object || yield raise GraphQL::Error, "Second definition of `subscription(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@subscription_object.inspect}" elsif use_visibility_profile? if block_given? if visibility.preload? @subscription_object = lazy_load_block.call visibility.subscription_configured(@subscription_object) else @subscription_object = lazy_load_block end else @subscription_object = new_subscription_object self.visibility.subscription_configured(@subscription_object) end add_subscription_extension_if_necessary else @subscription_object = new_subscription_object || lazy_load_block.call add_subscription_extension_if_necessary add_type_and_traverse(@subscription_object, root: true) end nil elsif @subscription_object.is_a?(Proc) @subscription_object = @subscription_object.call add_subscription_extension_if_necessary self.visibility.subscription_configured(@subscription_object) @subscription_object else @subscription_object || find_inherited_value(:subscription) end end |
.subscription_execution_strategy(new_subscription_execution_strategy = nil, deprecation_warning: true) ⇒ Object
834 835 836 837 838 839 840 841 842 843 844 |
# File 'lib/graphql/schema.rb', line 834 def subscription_execution_strategy(new_subscription_execution_strategy = nil, deprecation_warning: true) if deprecation_warning warn "GraphQL::Schema.subscription_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead." warn " #{caller(1, 1).first}" end if new_subscription_execution_strategy @subscription_execution_strategy = new_subscription_execution_strategy else @subscription_execution_strategy || (superclass.respond_to?(:subscription_execution_strategy) ? superclass.subscription_execution_strategy(deprecation_warning: false) : self.default_execution_strategy) end end |
.subscriptions(inherited: true) ⇒ GraphQL::Subscriptions
143 144 145 |
# File 'lib/graphql/schema.rb', line 143 def subscriptions(inherited: true) defined?(@subscriptions) ? @subscriptions : (inherited ? find_inherited_value(:subscriptions, nil) : nil) end |
.subscriptions=(new_implementation) ⇒ Object
147 148 149 |
# File 'lib/graphql/schema.rb', line 147 def subscriptions=(new_implementation) @subscriptions = new_implementation end |
.sync_lazy(value) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Override this method to handle lazy objects in a custom way.
1681 1682 1683 1684 1685 1686 1687 1688 1689 |
# File 'lib/graphql/schema.rb', line 1681 def sync_lazy(value) lazy_method = lazy_method_name(value) if lazy_method synced_value = value.public_send(lazy_method) sync_lazy(synced_value) else value end end |
.to_definition(context: {}) ⇒ String
Return the GraphQL IDL for the schema
284 285 286 |
# File 'lib/graphql/schema.rb', line 284 def to_definition(context: {}) GraphQL::Schema::Printer.print_schema(self, context: context) end |
.to_document ⇒ GraphQL::Language::Document
Return the GraphQL::Language::Document IDL AST for the schema
290 291 292 |
# File 'lib/graphql/schema.rb', line 290 def to_document GraphQL::Language::DocumentFromSchemaDefinition.new(self).document end |
.to_json(**args) ⇒ String
Returns the JSON response of Introspection::INTROSPECTION_QUERY.
257 258 259 |
# File 'lib/graphql/schema.rb', line 257 def to_json(**args) JSON.pretty_generate(as_json(**args)) end |
.trace_class(new_class = nil) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/graphql/schema.rb', line 166 def trace_class(new_class = nil) if new_class # If any modules were already added for `:default`, # re-apply them here mods = trace_modules_for(:default) mods.each { |mod| new_class.include(mod) } new_class.include(DefaultTraceClass) trace_mode(:default, new_class) end trace_class_for(:default, build: true) end |
.trace_class_for(mode, build: false) ⇒ Class
Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn’t have one defined.
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/graphql/schema.rb', line 179 def trace_class_for(mode, build: false) if (trace_class = own_trace_modes[mode]) trace_class elsif superclass.respond_to?(:trace_class_for) && (trace_class = superclass.trace_class_for(mode, build: false)) trace_class elsif build own_trace_modes[mode] = build_trace_mode(mode) else nil end end |
.trace_mode(mode_name, trace_class) ⇒ Object
Configure trace_class to be used whenever context: { trace_mode: mode_name } is requested.
default_trace_mode is used when no trace_mode: ... is requested.
When a trace_class is added this way, it will not receive other modules added with trace_with(...)
unless trace_mode is explicitly given. (This class will not receive any default trace modules.)
Subclasses of the schema will use trace_class as a base class for this mode and those
subclass also will not receive default tracing modules.
203 204 205 206 |
# File 'lib/graphql/schema.rb', line 203 def trace_mode(mode_name, trace_class) own_trace_modes[mode_name] = trace_class nil end |
.trace_modules_for(trace_mode) ⇒ Array<Module>
Returns Modules added for tracing in trace_mode, including inherited ones.
245 246 247 248 249 250 251 |
# File 'lib/graphql/schema.rb', line 245 def trace_modules_for(trace_mode) modules = own_trace_modules[trace_mode] if superclass.respond_to?(:trace_modules_for) modules += superclass.trace_modules_for(trace_mode) end modules end |
.trace_options_for(mode) ⇒ Hash
The options hash for this trace mode
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 |
# File 'lib/graphql/schema.rb', line 1502 def (mode) @trace_options_for_mode ||= {} @trace_options_for_mode[mode] ||= begin # It may be time to create an options hash for a mode that wasn't registered yet. # Mix in the default options in that case. = mode == :default ? EMPTY_HASH : (:default) # Make sure this returns a new object so that other hashes aren't modified later if superclass.respond_to?(:trace_options_for) superclass.(mode).merge() else .dup end end end |
.trace_with(trace_mod, mode: :default, **options) ⇒ void
This method returns an undefined value.
Mix trace_mod into this schema’s Trace class so that its methods will be called at runtime.
You can attach a module to run in only some circumstances by using mode:. When a module is added with mode:,
it will only run for queries with a matching context[:trace_mode].
Any custom trace modes also include the default trace_with ... modules (that is, those added without any particular mode: ... configuration).
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 |
# File 'lib/graphql/schema.rb', line 1472 def trace_with(trace_mod, mode: :default, **) if mode.is_a?(Array) mode.each { |m| trace_with(trace_mod, mode: m, **) } else tc = own_trace_modes[mode] ||= build_trace_mode(mode) tc.include(trace_mod) own_trace_modules[mode] << trace_mod (mode, ) if mode == :default # This module is being added as a default tracer. If any other mode classes # have already been created, but get their default behavior from a superclass, # Then mix this into this schema's subclass. # (But don't mix it into mode classes that aren't default-based.) own_trace_modes.each do |other_mode_name, other_mode_class| if other_mode_class < DefaultTraceClass # Don't add it back to the inheritance tree if it's already there if !(other_mode_class < trace_mod) other_mode_class.include(trace_mod) end # Add any options so they'll be available (other_mode_name, ) end end end end nil end |
.tracer(new_tracer, silence_deprecation_warning: false) ⇒ Object
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 |
# File 'lib/graphql/schema.rb', line 1439 def tracer(new_tracer, silence_deprecation_warning: false) if !silence_deprecation_warning warn("`Schema.tracer(#{new_tracer.inspect})` is deprecated; use module-based `trace_with` instead. See: https://graphql-ruby.org/queries/tracing.html") warn " #{caller(1, 1).first}" end default_trace = trace_class_for(:default, build: true) if default_trace.nil? || !(default_trace < GraphQL::Tracing::CallLegacyTracers) trace_with(GraphQL::Tracing::CallLegacyTracers) end own_tracers << new_tracer end |
.tracers ⇒ Object
1452 1453 1454 |
# File 'lib/graphql/schema.rb', line 1452 def tracers find_inherited_value(:tracers, EMPTY_ARRAY) + own_tracers end |
.type_error(type_error, context) ⇒ void
This method returns an undefined value.
Called at runtime when GraphQL-Ruby encounters a mismatch between the application behavior and the GraphQL type system.
The default implementation of this method is to follow the GraphQL specification, but you can override this to report errors to your bug tracker or customize error handling.
1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 |
# File 'lib/graphql/schema.rb', line 1336 def type_error(type_error, context) case type_error when GraphQL::InvalidNullError execution_error = GraphQL::ExecutionError.new(type_error., ast_nodes: type_error.ast_nodes) execution_error.path = type_error.path || context[:current_path] context.errors << execution_error execution_error when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError, GraphQL::IntegerEncodingError raise type_error when GraphQL::IntegerDecodingError nil end end |
.type_from_ast(ast_node, context: self.query_class.new(self, "{ __typename }").context) ⇒ Object
706 707 708 |
# File 'lib/graphql/schema.rb', line 706 def type_from_ast(ast_node, context: self.query_class.new(self, "{ __typename }").context) GraphQL::Schema::TypeExpression.build_type(context.query.types, ast_node) end |
.types(context = null_context) ⇒ Hash<String => Class>
Build a map of { name => type } and return it
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/graphql/schema.rb', line 342 def types(context = null_context) if use_visibility_profile? types = Visibility::Profile.from_context(context, self) return types.all_types_h end all_types = non_introspection_types.merge(introspection_system.types) visible_types = {} all_types.each do |k, v| visible_types[k] =if v.is_a?(Array) visible_t = nil v.each do |t| if t.visible?(context) if visible_t.nil? visible_t = t else raise DuplicateNamesError.new( duplicated_name: k, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect ) end end end visible_t else v end end visible_types end |
.unauthorized_field(unauthorized_error) ⇒ Field
This hook is called when a field fails an authorized? check.
By default, this hook implements the same behavior as unauthorized_object.
Whatever value is returned from this method will be used instead of the
unauthorized field . If an error is raised, then nil will be used.
If you want to add an error to the "errors" key, raise a ExecutionError
in this hook.
1322 1323 1324 |
# File 'lib/graphql/schema.rb', line 1322 def () () end |
.unauthorized_object(unauthorized_error) ⇒ Object
This hook is called when an object fails an authorized? check.
You might report to your bug tracker here, so you can correct
the field resolvers not to return unauthorized objects.
By default, this hook just replaces the unauthorized object with nil.
Whatever value is returned from this method will be used instead of the
unauthorized object (accessible as unauthorized_error.object). If an
error is raised, then nil will be used.
If you want to add an error to the "errors" key, raise a ExecutionError
in this hook.
1306 1307 1308 |
# File 'lib/graphql/schema.rb', line 1306 def () nil end |
.union_memberships(type = nil) ⇒ Object
662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'lib/graphql/schema.rb', line 662 def union_memberships(type = nil) if type own_um = own_union_memberships.fetch(type.graphql_name, EMPTY_ARRAY) inherited_um = find_inherited_value(:union_memberships, EMPTY_HASH).fetch(type.graphql_name, EMPTY_ARRAY) own_um + inherited_um else joined_um = own_union_memberships.dup find_inherited_value(:union_memberhips, EMPTY_HASH).each do |k, v| um = joined_um[k] ||= [] um.concat(v) end joined_um end end |
.use(plugin, **kwargs) ⇒ Object
Add plugin to this schema
320 321 322 323 324 325 326 327 |
# File 'lib/graphql/schema.rb', line 320 def use(plugin, **kwargs) if !kwargs.empty? plugin.use(self, **kwargs) else plugin.use(self) end own_plugins << [plugin, kwargs] end |
.use_visibility_profile? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
611 612 613 614 615 616 617 618 619 |
# File 'lib/graphql/schema.rb', line 611 def use_visibility_profile? if defined?(@use_visibility_profile) @use_visibility_profile elsif superclass.respond_to?(:use_visibility_profile?) superclass.use_visibility_profile? else false end end |
.uses_raw_value(new_val) ⇒ Object
1369 1370 1371 |
# File 'lib/graphql/schema.rb', line 1369 def uses_raw_value(new_val) @uses_raw_value = new_val end |
.uses_raw_value? ⇒ Boolean
1365 1366 1367 |
# File 'lib/graphql/schema.rb', line 1365 def uses_raw_value? !!@uses_raw_value end |
.validate(string_or_document, rules: nil, context: nil) ⇒ Array<GraphQL::StaticValidation::Error >
Validate a query string according to this schema.
861 862 863 864 865 866 867 868 869 870 871 872 873 |
# File 'lib/graphql/schema.rb', line 861 def validate(string_or_document, rules: nil, context: nil) doc = if string_or_document.is_a?(String) GraphQL.parse(string_or_document) else string_or_document end query = query_class.new(self, document: doc, context: context) validator_opts = { schema: self } rules && (validator_opts[:rules] = rules) validator = GraphQL::StaticValidation::Validator.new(**validator_opts) res = validator.validate(query, timeout: validate_timeout, max_errors: validate_max_errors) res[:errors] end |
.visible?(member, ctx) ⇒ Boolean
1274 1275 1276 |
# File 'lib/graphql/schema.rb', line 1274 def visible?(member, ctx) member.visible?(ctx) end |