Async-Microservice

 view release on metacpan or  search on metacpan

lib/Async/Microservice.pm  view on Meta::CPAN


        # without version path redirect to the latest version
        return $this_req->redirect( '/v' . $self->api_version . '/' )
            unless $version;

        if ( my $match = $self->router->match($sub_path_info) ) {
            my $func = $match->{mapping}->{ $this_req->method };
            if ( $func && ( my $misc_fn = $self->can($func) ) ) {
                %{ $this_req->params } =
                    ( %{ $this_req->params }, %{ $match->{mapping} } );
                my $resp = $misc_fn->( $self, $this_req, $match );
                if ( blessed($resp) && $resp->isa('Future') ) {
                    $resp->retain;
                    $resp->on_done(
                        sub {
                            my ($resp_data) = @_;
                            if ( ref($resp_data) eq 'ARRAY' ) {
                                $this_req->respond(@$resp_data);
                            }
                            else {
                                $this_req->respond( 200, [], $resp_data );
                            }
                        }
                    );
                    $resp->on_fail(
                        sub {
                            my ($err_msg) = @_;
                            $err_msg ||= 'unknown';
                            $log->errorf( 'exception while calling "%s": %s',
                                $plack_req->path_info, $err_msg );
                            $this_req->respond( 503, [],
                                      'internal server error calling '
                                    . $func . ': '
                                    . $err_msg );
                        }
                    );
                    $resp->on_cancel(
                        sub {
                            $this_req->respond( 429, [],
                                'request for ' . $func . ' canceled' );
                        }
                    );
                    return $resp;
                }
                elsif ( ref($resp) eq 'ARRAY' ) {
                    $this_req->respond(@$resp);
                }
                return;
            }
            else {
                # Route exists but method not supported
                my @allowed = grep { defined $match->{mapping}->{$_} }
                    keys %{ $match->{mapping} };
                return $this_req->respond(
                    405,
                    [ "Allow" => join( ", ", sort @allowed ) ],
                    'method not allowed'
                );
            }
        }
        return $this_req->respond( 404, [],
            'path ' . $sub_path_info . ' not found' );
    };

    return sub {
        my $respond  = shift;
        my $response = try {
            $plack_handler_sub->($respond);
        }
        catch {
            $this_req->respond( 503, [], 'internal server error: ' . $_ );
        };
        if ( blessed($response) && $response->isa('Future') ) {
            $response->on_done( sub { $this_req->clear_plack_respond } );
        }
        else {
            $this_req->clear_plack_respond;
        }
        return $response;
    };
}

sub _update_openapi_html {
    my ( $self, $content ) = @_;
    my $service_name             = $self->service_name;
    my $service_name_placeholder = $self->file_placeholder;
    $content =~ s/$service_name_placeholder/$service_name/g;
    return $content;
}

sub GET_root_index {
    my ( $self, $this_req ) = @_;
    return $this_req->static_ft( 'index.html',
        sub { $self->_update_openapi_html(@_) } );
}

sub GET_static {
    my ( $self, $this_req ) = @_;
    my $filename = $this_req->params->{filename};
    return $this_req->static_ft($filename);
}

sub GET_root_edit {
    my ( $self, $this_req ) = @_;
    return $this_req->static_ft( 'edit.html',
        sub { $self->_update_openapi_html(@_) } );
}

sub GET_hcheck {
    my ( $self, $this_req ) = @_;
    return $this_req->text_plain(
        'Service-Name: ' . $self->service_name,
        "API-Version: " . $self->api_version,
        'Uptime: ' . ( time() - $self->start_time ),
        'Request-Count: ' . $self->req_count,
        'Pending-Requests: ' . $self->pending_req,
    );
}

no Moose::Role;



( run in 1.506 second using v1.01-cache-2.11-cpan-39bf76dae61 )