graphql 1.9.21 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +44 -7
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +22 -27
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +29 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +17 -8
- data/lib/graphql/analysis/ast.rb +14 -14
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +37 -16
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +20 -17
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +108 -14
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +715 -387
- data/lib/graphql/execution/interpreter.rb +32 -31
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +32 -114
- data/lib/graphql/execution/multiplex.rb +60 -92
- data/lib/graphql/execution.rb +11 -3
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/base_object.rb +2 -5
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +5 -18
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +41 -11
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +10 -10
- data/lib/graphql/introspection/type_type.rb +27 -17
- data/lib/graphql/introspection.rb +99 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +99 -63
- data/lib/graphql/language/lexer.rb +53 -27
- data/lib/graphql/language/lexer.rl +5 -3
- data/lib/graphql/language/nodes.rb +64 -93
- data/lib/graphql/language/parser.rb +929 -896
- data/lib/graphql/language/parser.y +125 -102
- data/lib/graphql/language/printer.rb +11 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
- data/lib/graphql/pagination/array_connection.rb +77 -0
- data/lib/graphql/pagination/connection.rb +226 -0
- data/lib/graphql/pagination/connections.rb +134 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +226 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +51 -190
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +26 -11
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/validation_pipeline.rb +12 -38
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +26 -9
- data/lib/graphql/query.rb +62 -32
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +3 -0
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/range_add.rb +23 -9
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/schema/addition.rb +240 -0
- data/lib/graphql/schema/argument.rb +262 -28
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
- data/lib/graphql/schema/build_from_definition.rb +319 -220
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +2 -2
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +117 -14
- data/lib/graphql/schema/enum.rb +115 -22
- data/lib/graphql/schema/enum_value.rb +16 -21
- data/lib/graphql/schema/field/connection_extension.rb +46 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +376 -291
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +17 -1
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/input_object.rb +147 -60
- data/lib/graphql/schema/interface.rb +28 -43
- data/lib/graphql/schema/introspection_system.rb +101 -38
- data/lib/graphql/schema/late_bound_type.rb +3 -2
- data/lib/graphql/schema/list.rb +46 -3
- data/lib/graphql/schema/loader.rb +144 -102
- data/lib/graphql/schema/member/base_dsl_methods.rb +33 -32
- data/lib/graphql/schema/member/build_type.rb +23 -14
- data/lib/graphql/schema/member/has_arguments.rb +212 -23
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +99 -34
- data/lib/graphql/schema/member/has_interfaces.rb +88 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +11 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +34 -4
- data/lib/graphql/schema/object.rb +38 -65
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +57 -32
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +133 -79
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +19 -5
- data/lib/graphql/schema/union.rb +39 -14
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +182 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +687 -891
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/base_visitor.rb +21 -31
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +31 -19
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +85 -31
- data/lib/graphql/subscriptions/instrumentation.rb +0 -47
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +111 -52
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +14 -1
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +57 -29
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +15 -36
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +16 -8
- data/lib/graphql/types/iso_8601_date_time.rb +32 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -88
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +170 -0
- data/lib/graphql/types/relay/default_relay.rb +21 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +19 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +41 -58
- data/readme.md +3 -6
- metadata +97 -231
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -159
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -226
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -311
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -13
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -104
- data/lib/graphql/enum_type.rb +0 -193
- data/lib/graphql/execution/execute.rb +0 -326
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -330
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -153
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -154
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -86
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -81
- data/lib/graphql/object_type.rb +0 -141
- data/lib/graphql/query/arguments.rb +0 -187
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -172
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -40
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -18
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -190
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -133
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -74
- data/lib/graphql/tracing/skylight_tracing.rb +0 -62
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -135
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
|
6
|
+
# This class uses the AppopticsAPM SDK from the appoptics_apm gem to create
|
7
|
+
# traces for GraphQL.
|
8
|
+
#
|
9
|
+
# There are 4 configurations available. They can be set in the
|
10
|
+
# appoptics_apm config file or in code. Please see:
|
11
|
+
# {https://docs.appoptics.com/kb/apm_tracing/ruby/configure}
|
12
|
+
#
|
13
|
+
# AppOpticsAPM::Config[:graphql][:enabled] = true|false
|
14
|
+
# AppOpticsAPM::Config[:graphql][:transaction_name] = true|false
|
15
|
+
# AppOpticsAPM::Config[:graphql][:sanitize_query] = true|false
|
16
|
+
# AppOpticsAPM::Config[:graphql][:remove_comments] = true|false
|
17
|
+
class AppOpticsTracing < GraphQL::Tracing::PlatformTracing
|
18
|
+
# These GraphQL events will show up as 'graphql.prep' spans
|
19
|
+
PREP_KEYS = ['lex', 'parse', 'validate', 'analyze_query', 'analyze_multiplex'].freeze
|
20
|
+
# These GraphQL events will show up as 'graphql.execute' spans
|
21
|
+
EXEC_KEYS = ['execute_multiplex', 'execute_query', 'execute_query_lazy'].freeze
|
22
|
+
|
23
|
+
# During auto-instrumentation this version of AppOpticsTracing is compared
|
24
|
+
# with the version provided in the appoptics_apm gem, so that the newer
|
25
|
+
# version of the class can be used
|
26
|
+
|
27
|
+
def self.version
|
28
|
+
Gem::Version.new('1.0.0')
|
29
|
+
end
|
30
|
+
|
31
|
+
self.platform_keys = {
|
32
|
+
'lex' => 'lex',
|
33
|
+
'parse' => 'parse',
|
34
|
+
'validate' => 'validate',
|
35
|
+
'analyze_query' => 'analyze_query',
|
36
|
+
'analyze_multiplex' => 'analyze_multiplex',
|
37
|
+
'execute_multiplex' => 'execute_multiplex',
|
38
|
+
'execute_query' => 'execute_query',
|
39
|
+
'execute_query_lazy' => 'execute_query_lazy'
|
40
|
+
}
|
41
|
+
|
42
|
+
def platform_trace(platform_key, _key, data)
|
43
|
+
return yield if !defined?(AppOpticsAPM) || gql_config[:enabled] == false
|
44
|
+
|
45
|
+
layer = span_name(platform_key)
|
46
|
+
kvs = metadata(data, layer)
|
47
|
+
kvs[:Key] = platform_key if (PREP_KEYS + EXEC_KEYS).include?(platform_key)
|
48
|
+
|
49
|
+
transaction_name(kvs[:InboundQuery]) if kvs[:InboundQuery] && layer == 'graphql.execute'
|
50
|
+
|
51
|
+
::AppOpticsAPM::SDK.trace(layer, kvs) do
|
52
|
+
kvs.clear # we don't have to send them twice
|
53
|
+
yield
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def platform_field_key(type, field)
|
58
|
+
"graphql.#{type.graphql_name}.#{field.graphql_name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def platform_authorized_key(type)
|
62
|
+
"graphql.authorized.#{type.graphql_name}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def platform_resolve_type_key(type)
|
66
|
+
"graphql.resolve_type.#{type.graphql_name}"
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def gql_config
|
72
|
+
::AppOpticsAPM::Config[:graphql] ||= {}
|
73
|
+
end
|
74
|
+
|
75
|
+
def transaction_name(query)
|
76
|
+
return if gql_config[:transaction_name] == false ||
|
77
|
+
::AppOpticsAPM::SDK.get_transaction_name
|
78
|
+
|
79
|
+
split_query = query.strip.split(/\W+/, 3)
|
80
|
+
split_query[0] = 'query' if split_query[0].empty?
|
81
|
+
name = "graphql.#{split_query[0..1].join('.')}"
|
82
|
+
|
83
|
+
::AppOpticsAPM::SDK.set_transaction_name(name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def multiplex_transaction_name(names)
|
87
|
+
return if gql_config[:transaction_name] == false ||
|
88
|
+
::AppOpticsAPM::SDK.get_transaction_name
|
89
|
+
|
90
|
+
name = "graphql.multiplex.#{names.join('.')}"
|
91
|
+
name = "#{name[0..251]}..." if name.length > 254
|
92
|
+
|
93
|
+
::AppOpticsAPM::SDK.set_transaction_name(name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def span_name(key)
|
97
|
+
return 'graphql.prep' if PREP_KEYS.include?(key)
|
98
|
+
return 'graphql.execute' if EXEC_KEYS.include?(key)
|
99
|
+
|
100
|
+
key[/^graphql\./] ? key : "graphql.#{key}"
|
101
|
+
end
|
102
|
+
|
103
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
104
|
+
def metadata(data, layer)
|
105
|
+
data.keys.map do |key|
|
106
|
+
case key
|
107
|
+
when :context
|
108
|
+
graphql_context(data[key], layer)
|
109
|
+
when :query
|
110
|
+
graphql_query(data[key])
|
111
|
+
when :query_string
|
112
|
+
graphql_query_string(data[key])
|
113
|
+
when :multiplex
|
114
|
+
graphql_multiplex(data[key])
|
115
|
+
when :path
|
116
|
+
[key, data[key].join(".")]
|
117
|
+
else
|
118
|
+
[key, data[key]]
|
119
|
+
end
|
120
|
+
end.flatten(2).each_slice(2).to_h.merge(Spec: 'graphql')
|
121
|
+
end
|
122
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
123
|
+
|
124
|
+
def graphql_context(context, layer)
|
125
|
+
context.errors && context.errors.each do |err|
|
126
|
+
AppOpticsAPM::API.log_exception(layer, err)
|
127
|
+
end
|
128
|
+
|
129
|
+
[[:Path, context.path.join('.')]]
|
130
|
+
end
|
131
|
+
|
132
|
+
def graphql_query(query)
|
133
|
+
return [] unless query
|
134
|
+
|
135
|
+
query_string = query.query_string
|
136
|
+
query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
|
137
|
+
query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
|
138
|
+
|
139
|
+
[[:InboundQuery, query_string],
|
140
|
+
[:Operation, query.selected_operation_name]]
|
141
|
+
end
|
142
|
+
|
143
|
+
def graphql_query_string(query_string)
|
144
|
+
query_string = remove_comments(query_string) if gql_config[:remove_comments] != false
|
145
|
+
query_string = sanitize(query_string) if gql_config[:sanitize_query] != false
|
146
|
+
|
147
|
+
[:InboundQuery, query_string]
|
148
|
+
end
|
149
|
+
|
150
|
+
def graphql_multiplex(data)
|
151
|
+
names = data.queries.map(&:operations).map(&:keys).flatten.compact
|
152
|
+
multiplex_transaction_name(names) if names.size > 1
|
153
|
+
|
154
|
+
[:Operations, names.join(', ')]
|
155
|
+
end
|
156
|
+
|
157
|
+
def sanitize(query)
|
158
|
+
return unless query
|
159
|
+
|
160
|
+
# remove arguments
|
161
|
+
query.gsub(/"[^"]*"/, '"?"') # strings
|
162
|
+
.gsub(/-?[0-9]*\.?[0-9]+e?[0-9]*/, '?') # ints + floats
|
163
|
+
.gsub(/\[[^\]]*\]/, '[?]') # arrays
|
164
|
+
end
|
165
|
+
|
166
|
+
def remove_comments(query)
|
167
|
+
return unless query
|
168
|
+
|
169
|
+
query.gsub(/#[^\n\r]*/, '')
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -14,7 +14,22 @@ module GraphQL
|
|
14
14
|
"execute_query_lazy" => "execute.graphql",
|
15
15
|
}
|
16
16
|
|
17
|
+
# @param set_action_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
18
|
+
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
19
|
+
# It can also be specified per-query with `context[:set_appsignal_action_name]`.
|
20
|
+
def initialize(options = {})
|
21
|
+
@set_action_name = options.fetch(:set_action_name, false)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
17
25
|
def platform_trace(platform_key, key, data)
|
26
|
+
if key == "execute_query"
|
27
|
+
set_this_txn_name = data[:query].context[:set_appsignal_action_name]
|
28
|
+
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_action_name)
|
29
|
+
Appsignal::Transaction.current.set_action(transaction_name(data[:query]))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
18
33
|
Appsignal.instrument(platform_key) do
|
19
34
|
yield
|
20
35
|
end
|
@@ -23,6 +38,14 @@ module GraphQL
|
|
23
38
|
def platform_field_key(type, field)
|
24
39
|
"#{type.graphql_name}.#{field.graphql_name}.graphql"
|
25
40
|
end
|
41
|
+
|
42
|
+
def platform_authorized_key(type)
|
43
|
+
"#{type.graphql_name}.authorized.graphql"
|
44
|
+
end
|
45
|
+
|
46
|
+
def platform_resolve_type_key(type)
|
47
|
+
"#{type.graphql_name}.resolve_type.graphql"
|
48
|
+
end
|
26
49
|
end
|
27
50
|
end
|
28
51
|
end
|
@@ -20,7 +20,12 @@ module GraphQL
|
|
20
20
|
|
21
21
|
if key == 'execute_multiplex'
|
22
22
|
operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
|
23
|
-
span.resource =
|
23
|
+
span.resource = if operations.empty?
|
24
|
+
first_query = data[:multiplex].queries.first
|
25
|
+
fallback_transaction_name(first_query && first_query.context)
|
26
|
+
else
|
27
|
+
operations
|
28
|
+
end
|
24
29
|
|
25
30
|
# For top span of query, set the analytics sample rate tag, if available.
|
26
31
|
if analytics_enabled?
|
@@ -63,6 +68,14 @@ module GraphQL
|
|
63
68
|
def platform_field_key(type, field)
|
64
69
|
"#{type.graphql_name}.#{field.graphql_name}"
|
65
70
|
end
|
71
|
+
|
72
|
+
def platform_authorized_key(type)
|
73
|
+
"#{type.graphql_name}.authorized"
|
74
|
+
end
|
75
|
+
|
76
|
+
def platform_resolve_type_key(type)
|
77
|
+
"#{type.graphql_name}.resolve_type"
|
78
|
+
end
|
66
79
|
end
|
67
80
|
end
|
68
81
|
end
|
@@ -26,18 +26,7 @@ module GraphQL
|
|
26
26
|
if key == "execute_query"
|
27
27
|
set_this_txn_name = data[:query].context[:set_new_relic_transaction_name]
|
28
28
|
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
|
29
|
-
|
30
|
-
# Set the transaction name based on the operation type and name
|
31
|
-
selected_op = query.selected_operation
|
32
|
-
if selected_op
|
33
|
-
op_type = selected_op.operation_type
|
34
|
-
op_name = selected_op.name || "anonymous"
|
35
|
-
else
|
36
|
-
op_type = "query"
|
37
|
-
op_name = "anonymous"
|
38
|
-
end
|
39
|
-
|
40
|
-
NewRelic::Agent.set_transaction_name("GraphQL/#{op_type}.#{op_name}")
|
29
|
+
NewRelic::Agent.set_transaction_name(transaction_name(data[:query]))
|
41
30
|
end
|
42
31
|
end
|
43
32
|
|
@@ -49,6 +38,14 @@ module GraphQL
|
|
49
38
|
def platform_field_key(type, field)
|
50
39
|
"GraphQL/#{type.graphql_name}/#{field.graphql_name}"
|
51
40
|
end
|
41
|
+
|
42
|
+
def platform_authorized_key(type)
|
43
|
+
"GraphQL/Authorize/#{type.graphql_name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def platform_resolve_type_key(type)
|
47
|
+
"GraphQL/ResolveType/#{type.graphql_name}"
|
48
|
+
end
|
52
49
|
end
|
53
50
|
end
|
54
51
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
# This implementation forwards events to a notification handler (i.e.
|
6
|
+
# ActiveSupport::Notifications or Dry::Monitor::Notifications)
|
7
|
+
# with a `graphql` suffix.
|
8
|
+
#
|
9
|
+
# @see KEYS for event names
|
10
|
+
class NotificationsTracing
|
11
|
+
# A cache of frequently-used keys to avoid needless string allocations
|
12
|
+
KEYS = {
|
13
|
+
"lex" => "lex.graphql",
|
14
|
+
"parse" => "parse.graphql",
|
15
|
+
"validate" => "validate.graphql",
|
16
|
+
"analyze_multiplex" => "analyze_multiplex.graphql",
|
17
|
+
"analyze_query" => "analyze_query.graphql",
|
18
|
+
"execute_query" => "execute_query.graphql",
|
19
|
+
"execute_query_lazy" => "execute_query_lazy.graphql",
|
20
|
+
"execute_field" => "execute_field.graphql",
|
21
|
+
"execute_field_lazy" => "execute_field_lazy.graphql",
|
22
|
+
"authorized" => "authorized.graphql",
|
23
|
+
"authorized_lazy" => "authorized_lazy.graphql",
|
24
|
+
"resolve_type" => "resolve_type.graphql",
|
25
|
+
"resolve_type_lazy" => "resolve_type.graphql",
|
26
|
+
}
|
27
|
+
|
28
|
+
MAX_KEYS_SIZE = 100
|
29
|
+
|
30
|
+
# Initialize a new NotificationsTracing instance
|
31
|
+
#
|
32
|
+
# @param [Object] notifications_engine The notifications engine to use
|
33
|
+
def initialize(notifications_engine)
|
34
|
+
@notifications_engine = notifications_engine
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sends a GraphQL tracing event to the notification handler
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# . notifications_engine = Dry::Monitor::Notifications.new(:graphql)
|
41
|
+
# . tracer = GraphQL::Tracing::NotificationsTracing.new(notifications_engine)
|
42
|
+
# . tracer.trace("lex") { ... }
|
43
|
+
#
|
44
|
+
# @param [string] key The key for the event
|
45
|
+
# @param [Hash] metadata The metadata for the event
|
46
|
+
# @yield The block to execute for the event
|
47
|
+
def trace(key, metadata, &blk)
|
48
|
+
prefixed_key = KEYS[key] || "#{key}.graphql"
|
49
|
+
|
50
|
+
# Cache the new keys while making sure not to induce a memory leak
|
51
|
+
if KEYS.size < MAX_KEYS_SIZE
|
52
|
+
KEYS[key] ||= prefixed_key
|
53
|
+
end
|
54
|
+
|
55
|
+
@notifications_engine.instrument(prefixed_key, metadata, &blk)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -21,7 +21,6 @@ module GraphQL
|
|
21
21
|
def trace(key, data)
|
22
22
|
case key
|
23
23
|
when "lex", "parse", "validate", "analyze_query", "analyze_multiplex", "execute_query", "execute_query_lazy", "execute_multiplex"
|
24
|
-
data.fetch(:query).context.namespace(self.class)[:platform_key_cache] = {} if key == "execute_query"
|
25
24
|
platform_key = @platform_keys.fetch(key)
|
26
25
|
platform_trace(platform_key, key, data) do
|
27
26
|
yield
|
@@ -33,18 +32,19 @@ module GraphQL
|
|
33
32
|
trace_field = true # implemented with instrumenter
|
34
33
|
else
|
35
34
|
field = data[:field]
|
36
|
-
platform_key_cache = data.fetch(:query).context.namespace(self.class).fetch(:platform_key_cache)
|
37
|
-
platform_key = platform_key_cache.fetch(field) do
|
38
|
-
platform_key_cache[field] = platform_field_key(data[:owner], field)
|
39
|
-
end
|
40
|
-
|
41
35
|
return_type = field.type.unwrap
|
42
|
-
|
43
|
-
trace_field = if return_type.respond_to?(:kind) && (return_type.kind.scalar? || return_type.kind.enum?)
|
36
|
+
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
44
37
|
(field.trace.nil? && @trace_scalars) || field.trace
|
45
38
|
else
|
46
39
|
true
|
47
40
|
end
|
41
|
+
|
42
|
+
platform_key = if trace_field
|
43
|
+
context = data.fetch(:query).context
|
44
|
+
cached_platform_key(context, field) { platform_field_key(data[:owner], field) }
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
48
|
end
|
49
49
|
|
50
50
|
if platform_key && trace_field
|
@@ -54,40 +54,68 @@ module GraphQL
|
|
54
54
|
else
|
55
55
|
yield
|
56
56
|
end
|
57
|
+
when "authorized", "authorized_lazy"
|
58
|
+
type = data.fetch(:type)
|
59
|
+
context = data.fetch(:context)
|
60
|
+
platform_key = cached_platform_key(context, type) { platform_authorized_key(type) }
|
61
|
+
platform_trace(platform_key, key, data) do
|
62
|
+
yield
|
63
|
+
end
|
64
|
+
when "resolve_type", "resolve_type_lazy"
|
65
|
+
type = data.fetch(:type)
|
66
|
+
context = data.fetch(:context)
|
67
|
+
platform_key = cached_platform_key(context, type) { platform_resolve_type_key(type) }
|
68
|
+
platform_trace(platform_key, key, data) do
|
69
|
+
yield
|
70
|
+
end
|
57
71
|
else
|
58
72
|
# it's a custom key
|
59
73
|
yield
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
when GraphQL::ScalarType, GraphQL::EnumType
|
67
|
-
if field.trace || (field.trace.nil? && @trace_scalars)
|
68
|
-
trace_field(type, field)
|
69
|
-
else
|
70
|
-
field
|
71
|
-
end
|
72
|
-
else
|
73
|
-
trace_field(type, field)
|
74
|
-
end
|
77
|
+
def self.use(schema_defn, options = {})
|
78
|
+
tracer = self.new(**options)
|
79
|
+
schema_defn.tracer(tracer)
|
75
80
|
end
|
76
81
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
82
|
+
private
|
83
|
+
|
84
|
+
# Get the transaction name based on the operation type and name if possible, or fall back to a user provided
|
85
|
+
# one. Useful for anonymous queries.
|
86
|
+
def transaction_name(query)
|
87
|
+
selected_op = query.selected_operation
|
88
|
+
txn_name = if selected_op
|
89
|
+
op_type = selected_op.operation_type
|
90
|
+
op_name = selected_op.name || fallback_transaction_name(query.context) || "anonymous"
|
91
|
+
"#{op_type}.#{op_name}"
|
92
|
+
else
|
93
|
+
"query.anonymous"
|
94
|
+
end
|
95
|
+
"GraphQL/#{txn_name}"
|
81
96
|
end
|
82
97
|
|
83
|
-
def
|
84
|
-
|
85
|
-
schema_defn.instrument(:field, tracer)
|
86
|
-
schema_defn.tracer(tracer)
|
98
|
+
def fallback_transaction_name(context)
|
99
|
+
context[:tracing_fallback_transaction_name]
|
87
100
|
end
|
88
101
|
|
89
|
-
private
|
90
102
|
attr_reader :options
|
103
|
+
|
104
|
+
# Different kind of schema objects have different kinds of keys:
|
105
|
+
#
|
106
|
+
# - Object types: `.authorized`
|
107
|
+
# - Union/Interface types: `.resolve_type`
|
108
|
+
# - Fields: execution
|
109
|
+
#
|
110
|
+
# So, they can all share one cache.
|
111
|
+
#
|
112
|
+
# If the key isn't present, the given block is called and the result is cached for `key`.
|
113
|
+
#
|
114
|
+
# @return [String]
|
115
|
+
def cached_platform_key(ctx, key)
|
116
|
+
cache = ctx.namespace(self.class)[:platform_key_cache] ||= {}
|
117
|
+
cache.fetch(key) { cache[key] = yield }
|
118
|
+
end
|
91
119
|
end
|
92
120
|
end
|
93
121
|
end
|
@@ -16,7 +16,10 @@ module GraphQL
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def collect(object)
|
19
|
-
|
19
|
+
default_labels = { key: object['key'], platform_key: object['platform_key'] }
|
20
|
+
custom = object['custom_labels']
|
21
|
+
labels = custom.nil? ? default_labels : default_labels.merge(custom)
|
22
|
+
|
20
23
|
@graphql_gauge.observe object['duration'], labels
|
21
24
|
end
|
22
25
|
|
@@ -36,6 +36,14 @@ module GraphQL
|
|
36
36
|
"#{type.graphql_name}.#{field.graphql_name}"
|
37
37
|
end
|
38
38
|
|
39
|
+
def platform_authorized_key(type)
|
40
|
+
"#{type.graphql_name}.authorized"
|
41
|
+
end
|
42
|
+
|
43
|
+
def platform_resolve_type_key(type)
|
44
|
+
"#{type.graphql_name}.resolve_type"
|
45
|
+
end
|
46
|
+
|
39
47
|
private
|
40
48
|
|
41
49
|
def instrument_execution(platform_key, key, data, &block)
|
@@ -16,12 +16,23 @@ module GraphQL
|
|
16
16
|
"execute_query_lazy" => "execute.graphql",
|
17
17
|
}
|
18
18
|
|
19
|
+
# @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
20
|
+
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
21
|
+
# It can also be specified per-query with `context[:set_scout_transaction_name]`.
|
19
22
|
def initialize(options = {})
|
20
23
|
self.class.include ScoutApm::Tracer
|
24
|
+
@set_transaction_name = options.fetch(:set_transaction_name, false)
|
21
25
|
super(options)
|
22
26
|
end
|
23
27
|
|
24
28
|
def platform_trace(platform_key, key, data)
|
29
|
+
if key == "execute_query"
|
30
|
+
set_this_txn_name = data[:query].context[:set_scout_transaction_name]
|
31
|
+
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
|
32
|
+
ScoutApm::Transaction.rename(transaction_name(data[:query]))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
25
36
|
self.class.instrument("GraphQL", platform_key, INSTRUMENT_OPTS) do
|
26
37
|
yield
|
27
38
|
end
|
@@ -30,6 +41,14 @@ module GraphQL
|
|
30
41
|
def platform_field_key(type, field)
|
31
42
|
"#{type.graphql_name}.#{field.graphql_name}"
|
32
43
|
end
|
44
|
+
|
45
|
+
def platform_authorized_key(type)
|
46
|
+
"#{type.graphql_name}.authorized"
|
47
|
+
end
|
48
|
+
|
49
|
+
def platform_resolve_type_key(type)
|
50
|
+
"#{type.graphql_name}.resolve_type"
|
51
|
+
end
|
33
52
|
end
|
34
53
|
end
|
35
54
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Tracing
|
5
|
+
class StatsdTracing < PlatformTracing
|
6
|
+
self.platform_keys = {
|
7
|
+
'lex' => "graphql.lex",
|
8
|
+
'parse' => "graphql.parse",
|
9
|
+
'validate' => "graphql.validate",
|
10
|
+
'analyze_query' => "graphql.analyze_query",
|
11
|
+
'analyze_multiplex' => "graphql.analyze_multiplex",
|
12
|
+
'execute_multiplex' => "graphql.execute_multiplex",
|
13
|
+
'execute_query' => "graphql.execute_query",
|
14
|
+
'execute_query_lazy' => "graphql.execute_query_lazy",
|
15
|
+
}
|
16
|
+
|
17
|
+
# @param statsd [Object] A statsd client
|
18
|
+
def initialize(statsd:, **rest)
|
19
|
+
@statsd = statsd
|
20
|
+
super(**rest)
|
21
|
+
end
|
22
|
+
|
23
|
+
def platform_trace(platform_key, key, data)
|
24
|
+
@statsd.time(platform_key) do
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def platform_field_key(type, field)
|
30
|
+
"graphql.#{type.graphql_name}.#{field.graphql_name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def platform_authorized_key(type)
|
34
|
+
"graphql.authorized.#{type.graphql_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def platform_resolve_type_key(type)
|
38
|
+
"graphql.resolve_type.#{type.graphql_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/graphql/tracing.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/tracing/active_support_notifications_tracing"
|
3
3
|
require "graphql/tracing/platform_tracing"
|
4
|
+
require "graphql/tracing/appoptics_tracing"
|
4
5
|
require "graphql/tracing/appsignal_tracing"
|
5
6
|
require "graphql/tracing/data_dog_tracing"
|
6
7
|
require "graphql/tracing/new_relic_tracing"
|
7
8
|
require "graphql/tracing/scout_tracing"
|
8
|
-
require "graphql/tracing/
|
9
|
+
require "graphql/tracing/statsd_tracing"
|
9
10
|
require "graphql/tracing/prometheus_tracing"
|
10
11
|
|
11
12
|
if defined?(PrometheusExporter::Server)
|
@@ -15,15 +16,13 @@ end
|
|
15
16
|
module GraphQL
|
16
17
|
# Library entry point for performance metric reporting.
|
17
18
|
#
|
18
|
-
# __Warning:__ Installing/uninstalling tracers is not thread-safe. Do it during application boot only.
|
19
|
-
#
|
20
19
|
# @example Sending custom events
|
21
|
-
#
|
20
|
+
# query.trace("my_custom_event", { ... }) do
|
22
21
|
# # do stuff ...
|
23
22
|
# end
|
24
23
|
#
|
25
24
|
# @example Adding a tracer to a schema
|
26
|
-
# MySchema
|
25
|
+
# class MySchema < GraphQL::Schema
|
27
26
|
# tracer MyTracer # <= responds to .trace(key, data, &block)
|
28
27
|
# end
|
29
28
|
#
|
@@ -42,8 +41,12 @@ module GraphQL
|
|
42
41
|
# execute_multiplex | `{ multiplex: GraphQL::Execution::Multiplex }`
|
43
42
|
# execute_query | `{ query: GraphQL::Query }`
|
44
43
|
# execute_query_lazy | `{ query: GraphQL::Query?, multiplex: GraphQL::Execution::Multiplex? }`
|
45
|
-
# execute_field | `{
|
46
|
-
# execute_field_lazy | `{
|
44
|
+
# execute_field | `{ owner: Class, field: GraphQL::Schema::Field, query: GraphQL::Query, path: Array<String, Integer>, ast_node: GraphQL::Language::Nodes::Field}`
|
45
|
+
# execute_field_lazy | `{ owner: Class, field: GraphQL::Schema::Field, query: GraphQL::Query, path: Array<String, Integer>, ast_node: GraphQL::Language::Nodes::Field}`
|
46
|
+
# authorized | `{ context: GraphQL::Query::Context, type: Class, object: Object, path: Array<String, Integer> }`
|
47
|
+
# authorized_lazy | `{ context: GraphQL::Query::Context, type: Class, object: Object, path: Array<String, Integer> }`
|
48
|
+
# resolve_type | `{ context: GraphQL::Query::Context, type: Class, object: Object, path: Array<String, Integer> }`
|
49
|
+
# resolve_type_lazy | `{ context: GraphQL::Query::Context, type: Class, object: Object, path: Array<String, Integer> }`
|
47
50
|
#
|
48
51
|
# Note that `execute_field` and `execute_field_lazy` receive different data in different settings:
|
49
52
|
#
|
@@ -58,8 +61,9 @@ module GraphQL
|
|
58
61
|
# @param key [String] The name of the event in GraphQL internals
|
59
62
|
# @param metadata [Hash] Event-related metadata (can be anything)
|
60
63
|
# @return [Object] Must return the value of the block
|
61
|
-
def trace(key, metadata)
|
62
|
-
|
64
|
+
def trace(key, metadata, &block)
|
65
|
+
return yield if @tracers.empty?
|
66
|
+
call_tracers(0, key, metadata, &block)
|
63
67
|
end
|
64
68
|
|
65
69
|
private
|
@@ -71,39 +75,14 @@ module GraphQL
|
|
71
75
|
# @param key [String] The current event name
|
72
76
|
# @param metadata [Object] The current event object
|
73
77
|
# @return Whatever the block returns
|
74
|
-
def call_tracers(idx, key, metadata)
|
78
|
+
def call_tracers(idx, key, metadata, &block)
|
75
79
|
if idx == @tracers.length
|
76
80
|
yield
|
77
81
|
else
|
78
|
-
@tracers[idx].trace(key, metadata) { call_tracers(idx + 1, key, metadata)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
class << self
|
84
|
-
# Install a tracer to receive events.
|
85
|
-
# @param tracer [<#trace(key, metadata)>]
|
86
|
-
# @return [void]
|
87
|
-
# @deprecated See {Schema#tracer} or use `context: { tracers: [...] }`
|
88
|
-
def install(tracer)
|
89
|
-
warn("GraphQL::Tracing.install is deprecated, add it to the schema with `tracer(my_tracer)` instead.")
|
90
|
-
if !tracers.include?(tracer)
|
91
|
-
@tracers << tracer
|
82
|
+
@tracers[idx].trace(key, metadata) { call_tracers(idx + 1, key, metadata, &block) }
|
92
83
|
end
|
93
84
|
end
|
94
|
-
|
95
|
-
# @deprecated See {Schema#tracer} or use `context: { tracers: [...] }`
|
96
|
-
def uninstall(tracer)
|
97
|
-
@tracers.delete(tracer)
|
98
|
-
end
|
99
|
-
|
100
|
-
# @deprecated See {Schema#tracer} or use `context: { tracers: [...] }`
|
101
|
-
def tracers
|
102
|
-
@tracers ||= []
|
103
|
-
end
|
104
85
|
end
|
105
|
-
# Initialize the array
|
106
|
-
tracers
|
107
86
|
|
108
87
|
module NullTracer
|
109
88
|
module_function
|