Search code examples
perlmojolicious

Mojolicious - how to intercept the incoming request before controller method handles and renders


In Mojolicious app, I need to figure out which controller method will be handling the incoming request so that I can log details of the remote client and add some logic. I want to do it at only one place and not in every controller methods. I have tried some of the HOOKS but could not figure out. Much appreciate any help on this.

Routes are generated/created from several OpenApi Plugin files and also use Oauth2 Plugin for OAuth.

  • Mojolicious detail:
CORE
  Perl        (v5.16.3, linux)
  Mojolicious (8.22, Supervillain)

OPTIONAL
  Cpanel::JSON::XS 4.04+  (n/a)
  EV 4.0+                 (4.22)
  IO::Socket::Socks 0.64+ (n/a)
  IO::Socket::SSL 2.009+  (2.060)
  Net::DNS::Native 0.15+  (n/a)
  Role::Tiny 2.000001+    (2.000005)


Solution

  • I asked in mojolicious mailing list and got the reply from the creator of the Mojolicious, Sebastian Riedel. Thanks.

    For everybody's benifit. $c->match->stack in around_action hook has the info I was looking for.

    Here is how:

    In your application startup method:

    sub startup {
        my $self = shift;
        ...
            $self->hook(
                around_action => sub {
                    my ($next, $c, $action, $last) = @_;
                    use DDP;
                    p $c->match; 
                    # prints all the info about the controller and the method/action
                    # it is going to call
                    ...
                }
            );
        ...
    }
    

    DDP - Output

    Mojolicious::Routes::Match  {
        Parents       Mojo::Base
        public methods (7) : endpoint, find, has, path_for, position, root, stack
        private methods (1) : _match
        internals: {
            endpoint   Mojolicious::Routes::Route,
            position   0,
            root       Mojolicious::Routes,
            stack      [
                [0] {
                    action               "controller_method_name",
                    controller           "ControllerClassName",
                    handler              "openapi",
                    id                   3336,
                    openapi.object       Mojolicious::Plugin::OpenAPI,
                    openapi.op_path      [
                        [0] "paths",
                        [1] "/api/endpoint/path/{id}/status",
                        [2] "get"
                    ],
                    openapi.parameters   [
                        [0] {
                            description   "job id",
                            in            "path",
                            name          "id",
                            required      JSON::PP::Boolean,
                            type          "number"
                        }
                    ]
                }
            ]
        }
    }
    

    Here is the info I am looking for in $c->match->stack:

                   action               "controller_method_name",
                   controller           "ControllerClassName",