Search code examples
perlmojolicious

Is it possible to overwrite the response data in a Mojo::Message::Response?


In a Mojolicious app I have a route in my Controller code like the following:

/account/:id/users

The /account/:id part of the route has the following data in it when I get to the users part of the chain:

$VAR1 = { 
    'signup_ip' => '172.17.5.146', 
    'z_id' => '382C58D8-529E-11E1-BDFB-A44585CCC763', 
    'signup_date' => '2012-03-12T12:11:10Z', 
    'name' => 'Some Cool Account Name', 
    'users' => [ 
        { 
            'user_id' => '382C67EC-529E-11E1-BDFB-A44585CCC763' 
        } 
    ], 
    'account_id' => '382C67EC-529E-11E1-BDFB-A44585CCC763',
}; 

In the users part of the chain I'm getting the above hash using $self->tx->res->content->get_body_chunk(0)

sub users { 
    my $self = shift; 
    my $user_list = from_json( $self->tx->res->content->get_body_chunk(0) );    
    $self->respond_to( json => $user_list->{users} );
} 

The problem I'm having is that I want to overwrite the response with only the users arrayref. The code above in sub users(){} doesn't do that. That is, when I dump the result in the test, I still getting the entire hash. The $user_list is the arrayref I'm looking for in users() but I'm unable to overwrite it.

Anyone have an idea how to do that?


Solution

  • Hrm I think I put my previous answer in the wrong place. So here it is:

    In the application I added the following routes:

    my $base = $r->bridge('/account/:id')->to('account#read');
    $base->route('/')->via('get')->to('account#index');
    $base->route('/users')->via('get')->to('account#users');
    

    In Acount.pm

    sub read {
        my $self = shift;
        # do stuff
    
        $self->stash->{account} = $data;   # set the stash
    
        return 1;     #return 1.  Don't render.
    }
    
    sub index {
        my $self = shift;
        my $data = $self->stash('account');  #get the stash 
    
         $self->render_json( $data );
    }
    
    sub users {
        my $self = shift;
        # do stuff
    
        my $data = $self->stash('account');
        $self->render_json( $data );
    }
    

    Doing this sets the result of /account/:id into the stash in the read sub. Setting a route to $base->route('/')->via('get')->to('account#index'); causes calls to /account/:id to be rendered from the index sub.

    The route $base->route('/users')->via('get')->to('account#users') causes the calls to /account/:id/users to be rendered from the users sub.