Search code examples
ruby-on-railsrubygraphqlwisper

Is it possible to integrate wisper with Ruby GraphQL?


I am looking to integrate wisper with my existing graphql api only ruby on rails project. Just wondering if there is any way to broadcast events from graphql mutations?

module Mutations
  module Order
    include Wisper::Publisher
    class Create < ::Mutations::BaseMutation
      argument :id, ID, required: true
      argument :date, String, required: true
      argument :category, String, required: true

      type Types::OrderType

      def resolve(**attributes)
        order = Order.new(attributes)
        if order.save!
          broadcast(:order_creation_successful, order.id)
          order
        end
      end
    end
  end
end

Global Subscriber

Rails.application.config.to_prepare do
  Wisper.clear if Rails.env.development? || Rails.env.test?

  Wisper.subscribe(
    OrderService::HandleExternalCalls,
    async: true,
    on: %i[order_creation_successful]
  )
end

Output - NoMethodError (private method `broadcast' called for #GraphqlController)

Error Trace:

{
"status": 500,
"error": "Internal Server Error",
"exception": "#<NoMethodError: undefined method `broadcast' for #<Mutations::Order::Create:0x00007f4b29492a70>>",
"traces": {
"Application Trace": [
{
"exception_object_id": 69980396152400,
"id": 0,
"trace": "app/graphql/mutations/order/create.rb:31:in `resolve'"
},
{
"exception_object_id": 69980396152400,
"id": 57,
"trace": "app/controllers/graphql_controller.rb:14:in `execute'"
}
],
"Framework Trace": [
{
"exception_object_id": 69980396152400,
"id": 1,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:95:in `public_send'"
},
{
"exception_object_id": 69980396152400,
"id": 2,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:95:in `block (3 levels) in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 3,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 4,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:83:in `block (2 levels) in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 5,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 6,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:76:in `block in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 7,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 8,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:65:in `resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 9,
"trace": "graphql (1.11.2) lib/graphql/schema/relay_classic_mutation.rb:64:in `resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 10,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:684:in `public_send'"
},
{
"exception_object_id": 69980396152400,
"id": 11,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:684:in `block in public_send_field'"
},
{
"exception_object_id": 69980396152400,
"id": 12,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:720:in `with_extensions'"
},
{
"exception_object_id": 69980396152400,
"id": 13,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:666:in `public_send_field'"
},
{
"exception_object_id": 69980396152400,
"id": 14,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:579:in `block in resolve'"
},
{
"exception_object_id": 69980396152400,
"id": 15,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 16,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:577:in `resolve'"
},
{
"exception_object_id": 69980396152400,
"id": 17,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:224:in `block (5 levels) in evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 18,
"trace": "graphql (1.11.2) lib/graphql/tracing.rb:66:in `trace'"
},
{
"exception_object_id": 69980396152400,
"id": 19,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:223:in `block (4 levels) in evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 20,
"trace": "graphql (1.11.2) lib/graphql/query.rb:353:in `block in with_error_handling'"
},
{
"exception_object_id": 69980396152400,
"id": 21,
"trace": "graphql (1.11.2) lib/graphql/execution/errors.rb:41:in `with_error_handling'"
},
{
"exception_object_id": 69980396152400,
"id": 22,
"trace": "graphql (1.11.2) lib/graphql/query.rb:352:in `with_error_handling'"
},
{
"exception_object_id": 69980396152400,
"id": 23,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:222:in `block (3 levels) in evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 24,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:384:in `resolve_with_directives'"
},
{
"exception_object_id": 69980396152400,
"id": 25,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:219:in `block (2 levels) in evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 26,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:459:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 27,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:177:in `block in evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 28,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:124:in `each'"
},
{
"exception_object_id": 69980396152400,
"id": 29,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:124:in `evaluate_selections'"
},
{
"exception_object_id": 69980396152400,
"id": 30,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter/runtime.rb:60:in `run_eager'"
},
{
"exception_object_id": 69980396152400,
"id": 31,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter.rb:73:in `block in evaluate'"
},
{
"exception_object_id": 69980396152400,
"id": 32,
"trace": "graphql (1.11.2) lib/graphql/tracing.rb:66:in `trace'"
},
{
"exception_object_id": 69980396152400,
"id": 33,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter.rb:72:in `evaluate'"
},
{
"exception_object_id": 69980396152400,
"id": 34,
"trace": "graphql (1.11.2) lib/graphql/execution/interpreter.rb:45:in `begin_query'"
},
{
"exception_object_id": 69980396152400,
"id": 35,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:112:in `begin_query'"
},
{
"exception_object_id": 69980396152400,
"id": 36,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:83:in `block in run_as_multiplex'"
},
{
"exception_object_id": 69980396152400,
"id": 37,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:82:in `map'"
},
{
"exception_object_id": 69980396152400,
"id": 38,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:82:in `run_as_multiplex'"
},
{
"exception_object_id": 69980396152400,
"id": 39,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:61:in `block (2 levels) in run_queries'"
},
{
"exception_object_id": 69980396152400,
"id": 40,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:195:in `block in instrument_and_analyze'"
},
{
"exception_object_id": 69980396152400,
"id": 41,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:29:in `block (2 levels) in apply_instrumenters'"
},
{
"exception_object_id": 69980396152400,
"id": 42,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:46:in `block (2 levels) in each_query_call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 43,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:41:in `each_query_call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 44,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:45:in `block in each_query_call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 45,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:72:in `call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 46,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:44:in `each_query_call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 47,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:27:in `block in apply_instrumenters'"
},
{
"exception_object_id": 69980396152400,
"id": 48,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:72:in `call_hooks'"
},
{
"exception_object_id": 69980396152400,
"id": 49,
"trace": "graphql (1.11.2) lib/graphql/execution/instrumentation.rb:26:in `apply_instrumenters'"
},
{
"exception_object_id": 69980396152400,
"id": 50,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:174:in `instrument_and_analyze'"
},
{
"exception_object_id": 69980396152400,
"id": 51,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:60:in `block in run_queries'"
},
{
"exception_object_id": 69980396152400,
"id": 52,
"trace": "graphql (1.11.2) lib/graphql/tracing.rb:66:in `trace'"
},
{
"exception_object_id": 69980396152400,
"id": 53,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:58:in `run_queries'"
},
{
"exception_object_id": 69980396152400,
"id": 54,
"trace": "graphql (1.11.2) lib/graphql/execution/multiplex.rb:48:in `run_all'"
},
{
"exception_object_id": 69980396152400,
"id": 55,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:1642:in `multiplex'"
},
{
"exception_object_id": 69980396152400,
"id": 56,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:1613:in `execute'"
},
{
"exception_object_id": 69980396152400,
"id": 58,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'"
},
{
"exception_object_id": 69980396152400,
"id": 59,
"trace": "actionpack (6.0.3.1) lib/abstract_controller/base.rb:195:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 60,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/rendering.rb:30:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 61,
"trace": "actionpack (6.0.3.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 62,
"trace": "activesupport (6.0.3.1) lib/active_support/callbacks.rb:135:in `run_callbacks'"
},
{
"exception_object_id": 69980396152400,
"id": 63,
"trace": "actionpack (6.0.3.1) lib/abstract_controller/callbacks.rb:41:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 64,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/rescue.rb:22:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 65,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 66,
"trace": "activesupport (6.0.3.1) lib/active_support/notifications.rb:180:in `block in instrument'"
},
{
"exception_object_id": 69980396152400,
"id": 67,
"trace": "activesupport (6.0.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'"
},
{
"exception_object_id": 69980396152400,
"id": 68,
"trace": "activesupport (6.0.3.1) lib/active_support/notifications.rb:180:in `instrument'"
},
{
"exception_object_id": 69980396152400,
"id": 69,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/instrumentation.rb:32:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 70,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 71,
"trace": "activerecord (6.0.3.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'"
},
{
"exception_object_id": 69980396152400,
"id": 72,
"trace": "actionpack (6.0.3.1) lib/abstract_controller/base.rb:136:in `process'"
},
{
"exception_object_id": 69980396152400,
"id": 73,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal.rb:190:in `dispatch'"
},
{
"exception_object_id": 69980396152400,
"id": 74,
"trace": "actionpack (6.0.3.1) lib/action_controller/metal.rb:254:in `dispatch'"
},
{
"exception_object_id": 69980396152400,
"id": 75,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'"
},
{
"exception_object_id": 69980396152400,
"id": 76,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'"
},
{
"exception_object_id": 69980396152400,
"id": 77,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'"
},
{
"exception_object_id": 69980396152400,
"id": 78,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `each'"
},
{
"exception_object_id": 69980396152400,
"id": 79,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'"
},
{
"exception_object_id": 69980396152400,
"id": 80,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:834:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 81,
"trace": "rack (2.2.3) lib/rack/etag.rb:27:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 82,
"trace": "rack (2.2.3) lib/rack/conditional_get.rb:40:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 83,
"trace": "rack (2.2.3) lib/rack/head.rb:12:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 84,
"trace": "activerecord (6.0.3.1) lib/active_record/migration.rb:567:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 85,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'"
},
{
"exception_object_id": 69980396152400,
"id": 86,
"trace": "activesupport (6.0.3.1) lib/active_support/callbacks.rb:101:in `run_callbacks'"
},
{
"exception_object_id": 69980396152400,
"id": 87,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 88,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 89,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 90,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 91,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 92,
"trace": "railties (6.0.3.1) lib/rails/rack/logger.rb:37:in `call_app'"
},
{
"exception_object_id": 69980396152400,
"id": 93,
"trace": "railties (6.0.3.1) lib/rails/rack/logger.rb:26:in `block in call'"
},
{
"exception_object_id": 69980396152400,
"id": 94,
"trace": "activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:80:in `block in tagged'"
},
{
"exception_object_id": 69980396152400,
"id": 95,
"trace": "activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:28:in `tagged'"
},
{
"exception_object_id": 69980396152400,
"id": 96,
"trace": "activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:80:in `tagged'"
},
{
"exception_object_id": 69980396152400,
"id": 97,
"trace": "railties (6.0.3.1) lib/rails/rack/logger.rb:26:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 98,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 99,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 100,
"trace": "rack (2.2.3) lib/rack/runtime.rb:22:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 101,
"trace": "activesupport (6.0.3.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 102,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 103,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/static.rb:126:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 104,
"trace": "rack (2.2.3) lib/rack/sendfile.rb:110:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 105,
"trace": "actionpack (6.0.3.1) lib/action_dispatch/middleware/host_authorization.rb:82:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 106,
"trace": "rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 107,
"trace": "railties (6.0.3.1) lib/rails/engine.rb:527:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 108,
"trace": "puma (3.12.6) lib/puma/configuration.rb:227:in `call'"
},
{
"exception_object_id": 69980396152400,
"id": 109,
"trace": "puma (3.12.6) lib/puma/server.rb:706:in `handle_request'"
},
{
"exception_object_id": 69980396152400,
"id": 110,
"trace": "puma (3.12.6) lib/puma/server.rb:476:in `process_client'"
},
{
"exception_object_id": 69980396152400,
"id": 111,
"trace": "puma (3.12.6) lib/puma/server.rb:334:in `block in run'"
},
{
"exception_object_id": 69980396152400,
"id": 112,
"trace": "puma (3.12.6) lib/puma/thread_pool.rb:135:in `block in spawn_thread'"
}
],
"Full Trace": [
{
"exception_object_id": 69980396152400,
"id": 0,
"trace": "app/graphql/mutations/order/create.rb:31:in `resolve'"
},
{
"exception_object_id": 69980396152400,
"id": 1,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:95:in `public_send'"
},
{
"exception_object_id": 69980396152400,
"id": 2,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:95:in `block (3 levels) in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 3,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 4,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:83:in `block (2 levels) in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 5,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 6,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:76:in `block in resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 7,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 8,
"trace": "graphql (1.11.2) lib/graphql/schema/resolver.rb:65:in `resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 9,
"trace": "graphql (1.11.2) lib/graphql/schema/relay_classic_mutation.rb:64:in `resolve_with_support'"
},
{
"exception_object_id": 69980396152400,
"id": 10,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:684:in `public_send'"
},
{
"exception_object_id": 69980396152400,
"id": 11,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:684:in `block in public_send_field'"
},
{
"exception_object_id": 69980396152400,
"id": 12,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:720:in `with_extensions'"
},
{
"exception_object_id": 69980396152400,
"id": 13,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:666:in `public_send_field'"
},
{
"exception_object_id": 69980396152400,
"id": 14,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:579:in `block in resolve'"
},
{
"exception_object_id": 69980396152400,
"id": 15,
"trace": "graphql (1.11.2) lib/graphql/schema.rb:112:in `after_lazy'"
},
{
"exception_object_id": 69980396152400,
"id": 16,
"trace": "graphql (1.11.2) lib/graphql/schema/field.rb:577:in `resolve'"
},
.
.
.
]
}
}

Is there any other alternative ruby gem to achieve this?


Solution

  • The exception you're getting is actually:

    #<NoMethodError: undefined method `broadcast' for #<Mutations::Order::Create:0x00007f4b29492a70>>
    

    The broadcast method appears to be added by the wisper gem. You've included Wisper::Publisher into the Mutations::Order module:

    module Mutations
      module Order
        include Wisper::Publisher
        class Create < ::Mutations::BaseMutation
          # stuff
          def resolve(**attributes)
            # stuff
          end
        end
      end
    end
    

    and the error is telling you that the Mutations::Order::Create object does not have the broadcast method defined. You probably want to do this instead:

        class Create < ::Mutations::BaseMutation      
          include Wisper::Publisher # will define the `broadcast` method
    
          # stuff
          def resolve(**attributes)
            # stuff
          end
        end