Just for fun (and to stay sharp with Mojo), I went ahead and coded up a little example of calling another HTTP API and getting the response asynchronously:
#!/usr/bin/env perl
use Mojolicious::Lite -signatures;
use Mojo::IOLoop;
use Mojo::DOM;
use Mojo::UserAgent;
use Mojo::Util qw/dumper/;
my $OTHER_API = 'http://localhost:3000/second_api';
post '/toMFF' => sub ($c) {
state $ua = Mojo::UserAgent->new;
my $body = $c->req->body;
my $dom = Mojo::DOM->new->xml(1)->parse($body); # example
my $quz = $dom->at('bar[quz]')->{quz};
$c->render_later;
$ua->post_p( $OTHER_API => form => { quz => $quz } )
->then(sub ($tx) {
my $res = $tx->result;
my %stash = ( code=>$res->code, msg=>$res->message,
timestamp => scalar gmtime, debugmessage=>"" );
if ($res->is_success) {
my $j = $res->json;
$stash{debugmessage} = "Server response: ".dumper($j);
if ( not $j->{response} ) {
$stash{code} = 599;
$stash{msg} = "Endpoint reported error";
}
}
else { $stash{debugmessage} = "HTTP error" }
$c->render('response', format=>'xml', %stash);
})->catch(sub ($err) {
# this sends a 500 response to the client:
$c->reply->exception("The endpoint could not be reached: $
+err");
});
};
# this API would actually be on a different server
post '/second_api' => sub ($c) {
my $quz = $c->param('quz');
my $resp = $quz && $quz=~/\S/
? { response => "Thanks for $quz!" }
: { error => "You didn't provide a quz" };
# pretend this API is a bit slow
$c->render_later;
Mojo::IOLoop->timer(1 => sub { $c->render(json=>$resp) });
};
app->start;
__DATA__
@@ response.xml.ep
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.1.009/cXML.d
+td">
<cXML payloadID="foo@ceprinter.com" xml:lang="en-US" timestamp="<%= $t
+imestamp %>">
<Response>
<Status code="<%= $code %>" text="<%= $msg %>" />
<!-- <%= $debugmessage %> -->
</Response>
</cXML>
Test with e.g. curl -X POST http://127.0.0.1:3000/toMFF -H "Content-Type: application/xml" -d '<foo><bar quz="baz"/></foo>'