I try to use Cro to create a Rest API that will publish messages in rabbitMQ. I would like to split my routes in different modules and compose them with an "include". But I would like to be able to share the same connection to rabbitMQ in each of those modules too. I try with "our" but it does not work :
File 1:
unit module XXX::YYY;
use Cro::HTTP::Router;
use Cro::HTTP::Server;
use Cro::HTTP::Log::File;
use XXX::YYY::Route1;
use Net::AMQP;
our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;
my $application = route {
include <api v1 run> => run-routes;
}
...
File 2:
unit module XXX::YYY::Route1;
use UUID;
use Cro::HTTP::Router;
use JSON::Fast;
use Net::AMQP;
my $channel = $XXX::YYY::rabbitConnection.open-channel().result;
$channel.declare-queue("test_task", durable=> True );
sub run-routes() is export { ... }
Error message:
===SORRY!===
No such method 'open-channel' for invocant of type 'Any'
Thanks!
When you define your exportable route function you can specify arguments then in your composing module you can create the shared objects and pass them to the routes. For example in your router module :
sub run-routes ($rmq) is export{
route {
... $rmq is available in here
}
}
Then in your main router you can create your Queue and pass it in when including
my $rmq = # Insert queue creation code here
include product => run-routes( $rmq );
I've not tried this but I can't see any reason why it shouldn't work.
The answer by @Scimon is certainly correct, but it does not addresses the OP. On the other hand, the two comments by @ugexe and @raiph are spot-on, so I'll try to summarize them here and explain what's going on.
This is the error:
Error message:
===SORRY!=== No such method 'open-channel' for invocant of type 'Any'
It indicates the invocant ($XXX::YYY::rabbitConnection
) is of type Any
, which is the type usually assigned to variables when they don't have a defined value; that is, basically, $XXX::YYY::rabbitConnection
is not defined. It certainly is not since XXX::YYY
is not included among the imported modules, as indicated by @ugexe.
That module was eliminated from the imported list because, as indicated by the OP
I certainly code it the wrong way because if i try to add use XXX::YYY;, i get a Circular module loading detected error
But of course. since use XXX::YYY::Route1;
which is file 2, is included in File 1.
That circular dependence probably points out to the fact that they should be in the same file, or else common code should be factored out to a third file, which would be eventually be included by both. So you should have something like unit module XXX::YYY::Common; use Net::AMQP;
our $rabbitConnection is export = Net::AMQP.new;
await $rabbitConnection.connect;
And then
use XXX::YYY::Common;
in both modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With