Mojolicious

 view release on metacpan or  search on metacpan

lib/Mojolicious/Guides/Cookbook.pod  view on Meta::CPAN

    $w = AE::timer 3, 0, sub {
      $c->render(text => 'Delayed by 3 seconds!');
      undef $w;
    };
  };

  app->start;

=head1 USER AGENT

When we say L<Mojolicious> is a web framework we actually mean it, with L<Mojo::UserAgent> there's a full featured HTTP
and WebSocket user agent built right in.

=head2 REST web services

Requests can be performed very comfortably with methods like L<Mojo::UserAgent/"get">, and always result in a
L<Mojo::Transaction::HTTP> object, which has many useful attributes and methods. You can check for connection errors
with L<Mojo::Transaction/"result">, or access HTTP request and response information directly through
L<Mojo::Transaction/"req"> and L<Mojo::Transaction/"res">.

  use Mojo::UserAgent;

  # Request a resource and make sure there were no connection errors
  my $ua = Mojo::UserAgent->new;
  my $tx = $ua->get('https://docs.mojolicious.org/Mojo' => {Accept => 'text/plain'});
  my $res = $tx->result;

  # Decide what to do with its representation
  if    ($res->is_success)  { say $res->body }
  elsif ($res->is_error)    { say $res->message }
  elsif ($res->code == 301) { say $res->headers->location }
  else                      { say 'Whatever...' }

While methods like L<Mojo::Message::Response/"is_success"> and L<Mojo::Message::Response/"is_error"> serve as building
blocks for more sophisticated REST clients.

=head2 Web scraping

Scraping information from websites has never been this much fun before. The built-in HTML/XML parser L<Mojo::DOM> is
accessible through L<Mojo::Message/"dom"> and supports all CSS selectors that make sense for a standalone parser, it
can be a very powerful tool especially for testing web application.

  use Mojo::UserAgent;

  # Fetch website
  my $ua = Mojo::UserAgent->new;
  my $res = $ua->get('https://docs.mojolicious.org')->result;

  # Extract title
  say 'Title: ', $res->dom->at('head > title')->text;

  # Extract headings
  $res->dom('h1, h2, h3')->each(sub ($dom, $i) {
    say 'Heading: ', $dom->all_text;
  });

  # Visit all nodes recursively to extract more than just text
  for my $n ($res->dom->descendant_nodes->each) {

    # Text or CDATA node
    print $n->content if $n->type eq 'text' || $n->type eq 'cdata';

    # Also include alternate text for images
    print $n->{alt} if $n->type eq 'tag' && $n->tag eq 'img';
  }

For a full list of available CSS selectors see L<Mojo::DOM::CSS/"SELECTORS">.

=head2 JSON web services

Most web services these days are based on the JSON data-interchange format. That's why L<Mojolicious> comes with the
possibly fastest pure-Perl implementation L<Mojo::JSON> built right in, which is accessible through
L<Mojo::Message/"json">.

  use Mojo::UserAgent;
  use Mojo::URL;

  # Fresh user agent
  my $ua = Mojo::UserAgent->new;

  # Search MetaCPAN for "mojolicious" and list latest releases
  my $url = Mojo::URL->new('http://fastapi.metacpan.org/v1/release/_search');
  $url->query({q => 'mojolicious', sort => 'date:desc'});
  for my $hit (@{$ua->get($url)->result->json->{hits}{hits}}) {
    say "$hit->{_source}{name} ($hit->{_source}{author})";
  }

=head2 Basic authentication

You can just add username and password to the URL, an C<Authorization> header will be automatically generated.

  use Mojo::UserAgent;

  my $ua = Mojo::UserAgent->new;
  say $ua->get('https://sri:secret@example.com/hideout')->result->body;

If you're using L<Mojo::URL> to build the URL, be aware that the userinfo part will not be included if the object is
stringified. You'll have to pass the object itself to L<Mojo::UserAgent> or use L<Mojo::URL/"to_unsafe_string">.

  use Mojo::UserAgent;
  use Mojo::URL;

  my $ua  = Mojo::UserAgent->new;
  my $url = Mojo::URL->new('https://example.com/hideout')->userinfo('sri:secret');
  say $ua->get($url)->result->body;

=head2 Decorating follow-up requests

L<Mojo::UserAgent> can automatically follow redirects, the event L<Mojo::UserAgent/"start"> allows you direct access to
each transaction right after they have been initialized and before a connection gets associated with them.

  use Mojo::UserAgent;

  # User agent following up to 10 redirects
  my $ua = Mojo::UserAgent->new(max_redirects => 10);

  # Add a witty header to every request
  $ua->on(start => sub ($ua, $tx) {
    $tx->req->headers->header('X-Bender' => 'Bite my shiny metal ass!');
    say 'Request: ', $tx->req->url->clone->to_abs;
  });



( run in 1.350 second using v1.01-cache-2.11-cpan-5837b0d9d2c )