Settings
prooph_service_bus:
command_buses:
default_command_bus: ~
query_buses:
default_query_bus: ~
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
Query\Handler\GetUserListHandler:
public: true
tags:
- { name: 'prooph_service_bus.default_query_bus.route_target' }
Controller
use Prooph\ServiceBus\QueryBus;
...
$this->queryBus->dispatch(
new GetUserList()
)->done(
function($result) {
\dump($result);
},
function($error) {
\dump($error);
}
) ;
Command has anything. Handler has one method:
public function __invoke(GetUserList $query, Deferred $deferred)
{
$i = random_int(1, 2);
if ($i % 2 === 0) {
$deferred->resolve('DONE!');
}
$deferred->reject('Out of luck');
}
ERROR
MessageDispatchException {#167303 ▼
#actionEvent: null
#message: "Message dispatch failed. See previous exception for details."
#code: 422
#file: "/var/www/site/vendor/prooph/service-bus/src/Exception/MessageDispatchException.php"
#line: 26
-previous: RuntimeException {#167300 ▼
#message: "Query Query\UseCase\GetUserList was not handled"
#code: 0
#file: "/var/www/site/vendor/prooph/service-bus/src/QueryBus.php"
#line: 103
trace: {▶}
}
trace: {▶}
}
Ok, lets try xml settings
<service id="Prooph\ServiceBus\QueryBus" alias="prooph_service_bus.default_query_bus"/>
<service id="Query\Handler\GetUserListHandler"
class="Query\Handler\GetUserListHandler"
public="true">
<tag name="prooph_service_bus.default_query_bus.route_target" message_detection="true"/>
</service>
and
<service id="Query\Handler\GetUserListHandler"
class="Handler\GetUserListHandler"
public="true"
>
<tag name="prooph_service_bus.default_query_bus.route_target"
message_detection="Query\UseCase\GetUserList"
// or
message_detection="true"
/>
</service>
Same error.
Remove any settings at all and try as in example from video https://www.youtube.com/watch?v=6EcQjVSj3m4
$queryRouter = new QueryRouter();
$queryRouter->route(GetUserList::class)->to( GetUserListHandler::class);
$queryRouter->attachToMessageBus($this->queryBus);
$this->queryBus->dispatch(
new GetUserList(
$filter,
$pagination,
$order
)
)->done(
function($result) {
\dump($result);
},
function($error) {
\dump($error);
},
function($progress) {
\dump($progress);
}
)
Still no luck, same error. Why it is not handled? Let us take a look log file
Initialized query message
--> message-data: { }
--> message-name: null
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message name for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message route for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Locate query handler for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Dispatching query Query\UseCase\GetUserList to handler
Query\Handler\GetUserListHandler
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Finished query: "Query\UseCase\GetUserList" by handler
Query\Handler\GetUserListHandler
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
Strange, handler found and defined, we have method but it still not handeld, why?
Lets try to pass object, but we do not want and need to pass object, because we have to use constructor when Handler invoked, to manage dependencies.
Changes:
$queryRouter->route(GetUserList::class)->to( new GetUserListHandler());
And THIS IS IT! IT WORKS! Let us see log and what the difference between working and not working samples
Initialized query message
--> message-data: { }
--> message-name: null
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message name for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message route for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Locate query handler for Query\UseCase\GetUserList
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Dispatching query Query\UseCase\GetUserList to handler
Query\Handler\GetUserListHandler
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Finished query: "Query\UseCase\GetUserList" by handler
Query\Handler\GetUserListHandler
--> message-data: { }
--> message-name: Query\UseCase\GetUserList
--> message-handled: true
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
No difference. Help me please to register Handler in xml service and make it work without every time using
$queryRouter = new QueryRouter();
$queryRouter->route(GetUserList::class)->to( new GetUserListHandler());
$queryRouter->attachToMessageBus($this->queryBus);
We have to initialize dependencies in constructor somehow and avoid such boilerplate like above.
In tactician we were using simply
<service id="League\Tactician\CommandBus" alias="tactician.commandbus.default"/>
<service id="GetSingleUserHandler" class="Query\Handler\GetUserListHandler">
<tag name="tactician.handler" typehints="true"/>
</service>
<service id="Prooph\ServiceBus\Plugin\Router\SingleHandlerRouter"
class="Prooph\ServiceBus\Plugin\Router\SingleHandlerRouter"
>
<argument type="collection" key="$messageMap">
<argument key="Query\UseCase\GetUserList">Query\Handler\GetUserListHandler</argument>
</argument>
</service>
//and
<service id="Query\Handler\GetUserListHandler"
class="Query\Handler\GetUserListHandler"
>
<tag name="prooph_service_bus.query_buses.default_query_bus.route_target"
message="Query\UseCase\GetUserList"
/>
</service>
<service id="Query\Handler\GetUserListHandler"
class="Query\Handler\GetUserListHandler"
>
<tag name="prooph_service_bus.query_buses.default_query_bus.route_target"
message_detection="true"
/>
</service>
Will return
MessageDispatchException {#3249 ▼
#actionEvent: null
#message: "Message dispatch failed. See previous exception for details."
#code: 422
#file: "/var/www/grabgg/vendor/prooph/service-bus/src/Exception/MessageDispatchException.php"
#line: 26
-previous: RuntimeException {#3246 ▼
#message: "QueryBus was not able to identify a Finder for query App\Application\CQRS\User\Query\UseCase\GetUserList"
#code: 0
I think it may be wrong tab and wrong repository for that issue sorry.
Can be close, found issue
<service id="GetUserListHandler" <<-------- HERE id must be different
class="App\Application\CQRS\User\Query\Handler\GetUserListHandler"
>
<tag name="prooph_service_bus.default_query_bus.route_target"
message="App\Application\CQRS\User\Query\UseCase\GetUserList"
/>
</service>
But please note issue with examples. Maybe docs update? And video with example seems to be outdated. ALso, message_detection does not work for me. "QueryBus was not able to identify a Finder for query " when
<tag name="prooph_service_bus.default_query_bus.route_target"
message_detection="true"
/>
Only "message" works
Thank you.