Newer Older
1252 lines | 36.888kb
add files
Yuki Kimoto authored on 2014-03-26
1

            
2
=encoding utf8
3

            
4
=head1 NAME
5

            
6
Mojolicious::Guides::Cookbook - Cookbook
7

            
8
=head1 OVERVIEW
9

            
10
This document contains many fun recipes for cooking with L<Mojolicious>.
11

            
12
=head1 DEPLOYMENT
13

            
14
Getting L<Mojolicious> and L<Mojolicious::Lite> applications running on
15
different platforms. Note that many real-time web features are based on the
16
L<Mojo::IOLoop> event loop, and therefore require one of the built-in web
17
servers to be able to use them to their full potential.
18

            
19
=head2 Built-in web server
20

            
21
L<Mojolicious> contains a very portable non-blocking I/O HTTP and WebSocket
22
server with L<Mojo::Server::Daemon>. It is usually used during development and
23
in the construction of more advanced web servers, but is solid and fast enough
24
for small to mid sized applications.
25

            
26
  $ ./script/myapp daemon
27
  Server available at http://127.0.0.1:3000.
28

            
29
It has many configuration options and is known to work on every platform Perl
30
works on.
31

            
32
  $ ./script/myapp daemon -h
33
  ...List of available options...
34

            
35
Another huge advantage is that it supports TLS and WebSockets out of the box,
36
a development certificate for testing purposes is built right in, so it just
37
works, but you can specify all listen locations supported by
38
L<Mojo::Server::Daemon/"listen">.
39

            
40
  $ ./script/myapp daemon -l https://*:3000
41
  Server available at https://127.0.0.1:3000.
42

            
43
On UNIX platforms you can also add preforking with L<Mojo::Server::Prefork>.
44

            
45
  $ ./script/myapp prefork
46
  Server available at http://127.0.0.1:3000.
47

            
48
Since all built-in web servers are based on the L<Mojo::IOLoop> event loop,
49
they scale best with non-blocking operations. But if your application for some
50
reason needs to perform many blocking operations, you can improve performance
51
by increasing the number of worker processes and decreasing the number of
52
concurrent connections each worker is allowed to handle.
53

            
54
  $ ./script/myapp prefork -m production -w 10 -c 1
55
  Server available at http://127.0.0.1:3000.
56

            
57
Your application is preloaded in the manager process during startup, to run
58
code whenever a new worker process has been forked you can use L<Mojo::IOLoop>
59
timers.
60

            
61
  use Mojolicious::Lite;
62

            
63
  Mojo::IOLoop->timer(0 => sub {
64
    app->log->info("Worker $$ star...ALL GLORY TO THE HYPNOTOAD!");
65
  });
66

            
67
  get '/' => {text => 'Hello Wor...ALL GLORY TO THE HYPNOTOAD!'};
68

            
69
  app->start;
70

            
71
=head2 Morbo
72

            
73
After reading the L<Mojolicious::Lite> tutorial, you should already be
74
familiar with L<Mojo::Server::Morbo>.
75

            
76
  Mojo::Server::Morbo
77
  +- Mojo::Server::Daemon
78

            
79
It is basically a restarter that forks a new L<Mojo::Server::Daemon> web
80
server whenever a file in your project changes, and should therefore only be
81
used during development.
82

            
83
  $ morbo script/myapp
84
  Server available at http://127.0.0.1:3000.
85

            
86
=head2 Hypnotoad
87

            
88
For bigger applications L<Mojolicious> contains the UNIX optimized preforking
89
web server L<Mojo::Server::Hypnotoad> that will allow you to take advantage of
90
multiple CPU cores and copy-on-write.
91

            
92
  Mojo::Server::Hypnotoad
93
  |- Mojo::Server::Daemon [1]
94
  |- Mojo::Server::Daemon [2]
95
  |- Mojo::Server::Daemon [3]
96
  +- Mojo::Server::Daemon [4]
97

            
98
It is based on the L<Mojo::Server::Prefork> web server, which adds preforking
99
to L<Mojo::Server::Daemon>, but optimized specifically for production
100
environments out of the box.
101

            
102
  $ hypnotoad script/myapp
103
  Server available at http://127.0.0.1:8080.
104

            
105
You can tweak many configuration settings right from within your application
106
with L<Mojo/"config">, for a full list see
107
L<Mojo::Server::Hypnotoad/"SETTINGS">.
108

            
109
  use Mojolicious::Lite;
110

            
111
  app->config(hypnotoad => {listen => ['http://*:80']});
112

            
113
  get '/' => {text => 'Hello Wor...ALL GLORY TO THE HYPNOTOAD!'};
114

            
115
  app->start;
116

            
117
Or just add a C<hypnotoad> section to your L<Mojolicious::Plugin::Config> or
118
L<Mojolicious::Plugin::JSONConfig> configuration file.
119

            
120
  # myapp.conf
121
  {
122
    hypnotoad => {
123
      listen  => ['https://*:443?cert=/etc/server.crt&key=/etc/server.key'],
124
      workers => 10
125
    }
126
  };
127

            
128
But one of its biggest advantages is the support for effortless zero downtime
129
software upgrades (hot deployment). That means you can upgrade L<Mojolicious>,
130
Perl or even system libraries at runtime without ever stopping the server or
131
losing a single incoming connection, just by running the command above again.
132

            
133
  $ hypnotoad script/myapp
134
  Starting hot deployment for Hypnotoad server 31841.
135

            
136
You might also want to enable proxy support if you're using Hypnotoad behind a
137
reverse proxy. This allows L<Mojolicious> to automatically pick up the
138
C<X-Forwarded-For> and C<X-Forwarded-HTTPS> headers.
139

            
140
  # myapp.conf
141
  {hypnotoad => {proxy => 1}};
142

            
143
=head2 Zero downtime software upgrades
144

            
145
Hypnotoad makes zero downtime software upgrades (hot deployment) very simple,
146
as you can see above, but on modern operating systems that support the
147
C<SO_REUSEPORT> socket option, there is also another method available that
148
works with all built-in web servers.
149

            
150
  $ ./script/myapp prefork -P /tmp/first.pid -l http://*:8080?reuse=1
151
  Server available at http://127.0.0.1:8080.
152

            
153
All you have to do is start a second web server listening to the same port and
154
stop the first web server gracefully afterwards.
155

            
156
  $ ./script/myapp prefork -P /tmp/second.pid -l http://*:8080?reuse=1
157
  Server available at http://127.0.0.1:8080.
158
  $ kill -s TERM `cat /tmp/first.pid`
159

            
160
Just remember that both web servers need to be started with the C<reuse>
161
parameter.
162

            
163
=head2 Nginx
164

            
165
One of the most popular setups these days is Hypnotoad behind an Nginx reverse
166
proxy, which even supports WebSockets in newer versions.
167

            
168
  upstream myapp {
169
    server 127.0.0.1:8080;
170
  }
171
  server {
172
    listen 80;
173
    server_name localhost;
174
    location / {
175
      proxy_pass http://myapp;
176
      proxy_http_version 1.1;
177
      proxy_set_header Upgrade $http_upgrade;
178
      proxy_set_header Connection "upgrade";
179
      proxy_set_header Host $host;
180
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
181
      proxy_set_header X-Forwarded-HTTPS 0;
182
    }
183
  }
184

            
185
=head2 Apache/mod_proxy
186

            
187
Another good reverse proxy is Apache with C<mod_proxy>, the configuration
188
looks quite similar to the Nginx one above.
189

            
190
  <VirtualHost *:80>
191
    ServerName localhost
192
    <Proxy *>
193
      Order deny,allow
194
      Allow from all
195
    </Proxy>
196
    ProxyRequests Off
197
    ProxyPreserveHost On
198
    ProxyPass / http://localhost:8080/ keepalive=On
199
    ProxyPassReverse / http://localhost:8080/
200
    RequestHeader set X-Forwarded-HTTPS "0"
201
  </VirtualHost>
202

            
203
=head2 Apache/CGI
204

            
205
C<CGI> is supported out of the box and your L<Mojolicious> application will
206
automatically detect that it is executed as a C<CGI> script.
207

            
208
  ScriptAlias / /home/sri/myapp/script/myapp/
209

            
210
=head2 PSGI/Plack
211

            
212
L<PSGI> is an interface between Perl web frameworks and web servers, and
213
L<Plack> is a Perl module and toolkit that contains L<PSGI> middleware,
214
helpers and adapters to web servers. L<PSGI> and L<Plack> are inspired by
215
Python's WSGI and Ruby's Rack. L<Mojolicious> applications are ridiculously
216
simple to deploy with L<Plack>.
217

            
218
  $ plackup ./script/myapp
219
  HTTP::Server::PSGI: Accepting connections at http://0:5000/
220

            
221
L<Plack> provides many server and protocol adapters for you to choose from,
222
such as C<FCGI>, C<uWSGI> and C<mod_perl>.
223

            
224
  $ plackup ./script/myapp -s FCGI -l /tmp/myapp.sock
225

            
226
If an older server adapter is not be able to correctly detect the application
227
home directory, you can simply use the MOJO_HOME environment variable.
228

            
229
  $ MOJO_HOME=/home/sri/myapp plackup ./script/myapp
230
  HTTP::Server::PSGI: Accepting connections at http://0:5000/
231

            
232
There is no need for a C<.psgi> file, just point the server adapter at your
233
application script, it will automatically act like one if it detects the
234
presence of a C<PLACK_ENV> environment variable.
235

            
236
=head2 Plack middleware
237

            
238
Wrapper scripts like C<myapp.fcgi> are a great way to separate deployment and
239
application logic.
240

            
241
  #!/usr/bin/env plackup -s FCGI
242
  use Plack::Builder;
243

            
244
  builder {
245
    enable 'Deflater';
246
    require 'myapp.pl';
247
  };
248

            
249
But you could even use middleware right in your application.
250

            
251
  use Mojolicious::Lite;
252
  use Plack::Builder;
253

            
254
  get '/welcome' => sub {
255
    my $self = shift;
256
    $self->render(text => 'Hello Mojo!');
257
  };
258

            
259
  builder {
260
    enable 'Deflater';
261
    app->start;
262
  };
263

            
264
=head2 Rewriting
265

            
266
Sometimes you might have to deploy your application in a blackbox environment
267
where you can't just change the server configuration or behind a reverse proxy
268
that passes along additional information with C<X-*> headers. In such cases
269
you can use the hook L<Mojolicious/"before_dispatch"> to rewrite incoming
270
requests.
271

            
272
  # Change scheme if "X-Forwarded-Protocol" header is set to "https"
273
  app->hook(before_dispatch => sub {
274
    my $c = shift;
275
    $c->req->url->base->scheme('https')
276
      if $c->req->headers->header('X-Forwarded-Protocol') eq 'https';
277
  });
278

            
279
Since reverse proxies generally don't pass along information about path
280
prefixes your application might be deployed under, rewriting the base path of
281
incoming requests is also quite common.
282

            
283
  # Move first part and slash from path to base path in production mode
284
  app->hook(before_dispatch => sub {
285
    my $c = shift;
286
    push @{$c->req->url->base->path->trailing_slash(1)},
287
      shift @{$c->req->url->path->leading_slash(0)};
288
  }) if app->mode eq 'production';
289

            
290
L<Mojo::URL> objects are very easy to manipulate, just make sure that the URL
291
(C<foo/bar?baz=yada>), which represents the routing destination, is always
292
relative to the base URL (C<http://example.com/myapp/>), which represents the
293
deployment location of your application.
294

            
295
=head2 Application embedding
296

            
297
From time to time you might want to reuse parts of L<Mojolicious> applications
298
like configuration files, database connection or helpers for other scripts,
299
with this little L<Mojo::Server> based mock server you can just embed them.
300

            
301
  use Mojo::Server;
302

            
303
  # Load application with mock server
304
  my $server = Mojo::Server->new;
305
  my $app = $server->load_app('./myapp.pl');
306

            
307
  # Access fully initialized application
308
  say for @{$app->static->paths};
309
  say $app->config->{secret_identity};
310
  say $app->dumper({just => 'a helper test'});
311

            
312
=head2 Web server embedding
313

            
314
You can also use L<Mojo::IOLoop/"one_tick"> to embed the built-in web server
315
L<Mojo::Server::Daemon> into alien environments like foreign event loops that
316
for some reason can't just be integrated with a new reactor backend.
317

            
318
  use Mojolicious::Lite;
319
  use Mojo::IOLoop;
320
  use Mojo::Server::Daemon;
321

            
322
  # Normal action
323
  get '/' => {text => 'Hello World!'};
324

            
325
  # Connect application with web server and start accepting connections
326
  my $daemon
327
    = Mojo::Server::Daemon->new(app => app, listen => ['http://*:8080']);
328
  $daemon->start;
329

            
330
  # Call "one_tick" repeatedly from the alien environment
331
  Mojo::IOLoop->one_tick while 1;
332

            
333
=head1 REAL-TIME WEB
334

            
335
The real-time web is a collection of technologies that include Comet
336
(long-polling), EventSource and WebSockets, which allow content to be pushed
337
to consumers with long-lived connections as soon as it is generated, instead
338
of relying on the more traditional pull model. All built-in web servers use
339
non-blocking I/O and are based on the L<Mojo::IOLoop> event loop, which
340
provides many very powerful features that allow real-time web applications to
341
scale up to thousands of clients.
342

            
343
=head2 Backend web services
344

            
345
Since L<Mojo::UserAgent> is also based on the L<Mojo::IOLoop> event loop, it
346
won't block the built-in web servers when used non-blocking, even for high
347
latency backend web services.
348

            
349
  use Mojolicious::Lite;
350

            
351
  # Search MetaCPAN for "mojolicious"
352
  get '/' => sub {
353
    my $self = shift;
354
    $self->ua->get('api.metacpan.org/v0/module/_search?q=mojolicious' => sub {
355
      my ($ua, $tx) = @_;
356
      $self->render('metacpan', hits => $tx->res->json->{hits}{hits});
357
    });
358
  };
359

            
360
  app->start;
361
  __DATA__
362

            
363
  @@ metacpan.html.ep
364
  <!DOCTYPE html>
365
  <html>
366
    <head><title>MetaCPAN results for "mojolicious"</title></head>
367
    <body>
368
      % for my $hit (@$hits) {
369
        <p><%= $hit->{_source}{release} %></p>
370
      % }
371
    </body>
372
  </html>
373

            
374
Multiple events such as parallel requests can be easily synchronized with
375
L<Mojo::IOLoop/"delay">.
376

            
377
  use Mojolicious::Lite;
378
  use Mojo::IOLoop;
379
  use Mojo::URL;
380

            
381
  # Search MetaCPAN for "mojo" and "mango"
382
  get '/' => sub {
383
    my $self = shift;
384

            
385
    # Prepare response in two steps
386
    Mojo::IOLoop->delay(
387

            
388
      # Parallel requests
389
      sub {
390
        my $delay = shift;
391
        my $url   = Mojo::URL->new('api.metacpan.org/v0/module/_search');
392
        $url->query({sort => 'date:desc'});
393
        $self->ua->get($url->clone->query({q => 'mojo'})  => $delay->begin);
394
        $self->ua->get($url->clone->query({q => 'mango'}) => $delay->begin);
395
      },
396

            
397
      # Delayed rendering
398
      sub {
399
        my ($delay, $mojo, $mango) = @_;
400
        $self->render(json => {
401
          mojo  => $mojo->res->json('/hits/hits/0/_source/release'),
402
          mango => $mango->res->json('/hits/hits/0/_source/release')
403
        });
404
      }
405
    );
406
  };
407

            
408
  app->start;
409

            
410
=head2 Timers
411

            
412
Another primary feature of the L<Mojo::IOLoop> event loop are timers, which
413
can for example be used to delay rendering of a response, and unlike C<sleep>,
414
won't block any other requests that might be processed in parallel.
415

            
416
  use Mojolicious::Lite;
417
  use Mojo::IOLoop;
418

            
419
  # Wait 3 seconds before rendering a response
420
  get '/' => sub {
421
    my $self = shift;
422
    Mojo::IOLoop->timer(3 => sub {
423
      $self->render(text => 'Delayed by 3 seconds!');
424
    });
425
  };
426

            
427
  app->start;
428

            
429
Recurring timers are slightly more powerful, but need to be stopped manually,
430
or they would just keep getting emitted.
431

            
432
  use Mojolicious::Lite;
433
  use Mojo::IOLoop;
434

            
435
  # Count to 5 in 1 second steps
436
  get '/' => sub {
437
    my $self = shift;
438

            
439
    # Start recurring timer
440
    my $i = 1;
441
    my $id = Mojo::IOLoop->recurring(1 => sub {
442
      $self->write_chunk($i);
443
      $self->finish if $i++ == 5;
444
    });
445

            
446
    # Stop recurring timer
447
    $self->on(finish => sub { Mojo::IOLoop->remove($id) });
448
  };
449

            
450
  app->start;
451

            
452
Timers are not tied to a specific request or connection, and can even be
453
created at startup time.
454

            
455
  use Mojolicious::Lite;
456
  use Mojo::IOLoop;
457

            
458
  # Count seconds since startup
459
  my $i = 0;
460
  Mojo::IOLoop->recurring(1 => sub { $i++ });
461

            
462
  # Show counter
463
  get '/' => sub {
464
    my $self = shift;
465
    $self->render(text => "About $i seconds running!");
466
  };
467

            
468
  app->start;
469

            
470
Since timers and other low level event watchers are also independent from
471
applications, errors can't get logged automatically, you can change that by
472
subscribing to the event L<Mojo::Reactor/"error">.
473

            
474
  # Forward error messages to the application log
475
  Mojo::IOLoop->singleton->reactor->on(error => sub {
476
    my ($reactor, $err) = @_;
477
    app->log->error($err);
478
  });
479

            
480
Just remember that all events are processed cooperatively, so your callbacks
481
shouldn't block for too long.
482

            
483
=head2 WebSocket web service
484

            
485
The WebSocket protocol offers full bi-directional low-latency communication
486
channels between clients and servers. Receive messages just by subscribing to
487
events such as L<Mojo::Transaction::WebSocket/"message"> with the method
488
L<Mojolicious::Controller/"on"> and return them with
489
L<Mojolicious::Controller/"send">.
490

            
491
  use Mojolicious::Lite;
492
  use Mojo::IOLoop;
493

            
494
  # Template with browser-side code
495
  get '/' => 'index';
496

            
497
  # WebSocket echo service
498
  websocket '/echo' => sub {
499
    my $self = shift;
500

            
501
    # Opened
502
    $self->app->log->debug('WebSocket opened.');
503

            
504
    # Increase inactivity timeout for connection a bit
505
    Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
506

            
507
    # Incoming message
508
    $self->on(message => sub {
509
      my ($self, $msg) = @_;
510
      $self->send("echo: $msg");
511
    });
512

            
513
    # Closed
514
    $self->on(finish => sub {
515
      my ($self, $code, $reason) = @_;
516
      $self->app->log->debug("WebSocket closed with status $code.");
517
    });
518
  };
519

            
520
  app->start;
521
  __DATA__
522

            
523
  @@ index.html.ep
524
  <!DOCTYPE html>
525
  <html>
526
    <head><title>Echo</title></head>
527
    <body>
528
      <script>
529
        var ws = new WebSocket('<%= url_for('echo')->to_abs %>');
530

            
531
        // Incoming messages
532
        ws.onmessage = function(event) {
533
          document.body.innerHTML += event.data + '<br/>';
534
        };
535

            
536
        // Outgoing messages
537
        window.setInterval(function() {
538
          ws.send('Hello Mojo!');
539
        }, 1000);
540
      </script>
541
    </body>
542
  </html>
543

            
544
The event L<Mojo::Transaction::WebSocket/"finish"> will be emitted right after
545
the WebSocket connection has been closed.
546

            
547
=head2 Testing WebSocket web services
548

            
549
While the message flow on WebSocket connections can be rather dynamic, it
550
more often than not is quite predictable, which allows this rather pleasant
551
L<Test::Mojo> API to be used.
552

            
553
  use Test::More;
554
  use Test::Mojo;
555

            
556
  # Include application
557
  use FindBin;
558
  require "$FindBin::Bin/../echo.pl";
559

            
560
  # Test echo web service
561
  my $t = Test::Mojo->new;
562
  $t->websocket_ok('/echo')
563
    ->send_ok('Hello Mojo!')
564
    ->message_ok
565
    ->message_is('echo: Hello Mojo!')
566
    ->finish_ok;
567

            
568
  # Test JSON web service
569
  $t->websocket_ok('/echo.json')
570
    ->send_ok({json => {test => [1, 2, 3]}})
571
    ->message_ok
572
    ->json_message_is('/test', [1, 2, 3])
573
    ->finish_ok;
574

            
575
  done_testing();
576

            
577
=head2 EventSource web service
578

            
579
EventSource is a special form of long-polling where you can use
580
L<Mojolicious::Controller/"write"> to directly send DOM events from servers to
581
clients. It is uni-directional, that means you will have to use Ajax requests
582
for sending data from clients to servers, the advantage however is low
583
infrastructure requirements, since it reuses the HTTP protocol for transport.
584

            
585
  use Mojolicious::Lite;
586
  use Mojo::IOLoop;
587

            
588
  # Template with browser-side code
589
  get '/' => 'index';
590

            
591
  # EventSource for log messages
592
  get '/events' => sub {
593
    my $self = shift;
594

            
595
    # Increase inactivity timeout for connection a bit
596
    Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
597

            
598
    # Change content type
599
    $self->res->headers->content_type('text/event-stream');
600

            
601
    # Subscribe to "message" event and forward "log" events to browser
602
    my $cb = $self->app->log->on(message => sub {
603
      my ($log, $level, @lines) = @_;
604
      $self->write("event:log\ndata: [$level] @lines\n\n");
605
    });
606

            
607
    # Unsubscribe from "message" event again once we are done
608
    $self->on(finish => sub {
609
      my $self = shift;
610
      $self->app->log->unsubscribe(message => $cb);
611
    });
612
  };
613

            
614
  app->start;
615
  __DATA__
616

            
617
  @@ index.html.ep
618
  <!DOCTYPE html>
619
  <html>
620
    <head><title>LiveLog</title></head>
621
    <body>
622
      <script>
623
        var events = new EventSource('<%= url_for 'events' %>');
624

            
625
        // Subscribe to "log" event
626
        events.addEventListener('log', function(event) {
627
          document.body.innerHTML += event.data + '<br/>';
628
        }, false);
629
      </script>
630
    </body>
631
  </html>
632

            
633
The event L<Mojo::Log/"message"> will be emitted for every new log message and
634
the event L<Mojo::Transaction/"finish"> right after the transaction has been
635
finished.
636

            
637
=head2 Streaming multipart uploads
638

            
639
L<Mojolicious> contains a very sophisticated event system based on
640
L<Mojo::EventEmitter>, with ready-to-use events on almost all layers, and
641
which can be combined to solve some of hardest problems in web development.
642

            
643
  use Mojolicious::Lite;
644
  use Scalar::Util 'weaken';
645

            
646
  # Emit "request" event early for requests that get upgraded to multipart
647
  hook after_build_tx => sub {
648
    my $tx = shift;
649
    weaken $tx;
650
    $tx->req->content->on(upgrade => sub { $tx->emit('request') });
651
  };
652

            
653
  # Upload form in DATA section
654
  get '/' => 'index';
655

            
656
  # Streaming multipart upload (invoked twice, due to early "request" event)
657
  post '/upload' => sub {
658
    my $self = shift;
659

            
660
    # First invocation, subscribe to "part" event to find the right one
661
    return $self->req->content->on(part => sub {
662
      my ($multi, $single) = @_;
663

            
664
      # Subscribe to "body" event of part to make sure we have all headers
665
      $single->on(body => sub {
666
        my $single = shift;
667

            
668
        # Make sure we have the right part and replace "read" event
669
        return unless $single->headers->content_disposition =~ /example/;
670
        $single->unsubscribe('read')->on(read => sub {
671
          my ($single, $bytes) = @_;
672

            
673
          # Log size of every chunk we receive
674
          $self->app->log->debug(length($bytes) . ' bytes uploaded.');
675
        });
676
      });
677
    }) unless $self->req->is_finished;
678

            
679
    # Second invocation, render response
680
    $self->render(text => 'Upload was successful.');
681
  };
682

            
683
  app->start;
684
  __DATA__
685

            
686
  @@ index.html.ep
687
  <!DOCTYPE html>
688
  <html>
689
    <head><title>Streaming multipart upload</title></head>
690
    <body>
691
      %= form_for upload => (enctype => 'multipart/form-data') => begin
692
        %= file_field 'example'
693
        %= submit_button 'Upload'
694
      % end
695
    </body>
696
  </html>
697

            
698
=head2 Event loops
699

            
700
Internally the L<Mojo::IOLoop> event loop can use multiple reactor backends,
701
L<EV> for example will be automatically used if installed. Which in turn
702
allows other event loops like L<AnyEvent> to just work.
703

            
704
  use Mojolicious::Lite;
705
  use EV;
706
  use AnyEvent;
707

            
708
  # Wait 3 seconds before rendering a response
709
  get '/' => sub {
710
    my $self = shift;
711
    my $w;
712
    $w = AE::timer 3, 0, sub {
713
      $self->render(text => 'Delayed by 3 seconds!');
714
      undef $w;
715
    };
716
  };
717

            
718
  app->start;
719

            
720
Who actually controls the event loop backend is not important.
721

            
722
  use Mojo::UserAgent;
723
  use EV;
724
  use AnyEvent;
725

            
726
  # Search MetaCPAN for "mojolicious"
727
  my $cv = AE::cv;
728
  my $ua = Mojo::UserAgent->new;
729
  $ua->get('api.metacpan.org/v0/module/_search?q=mojolicious' => sub {
730
    my ($ua, $tx) = @_;
731
    $cv->send($tx->res->json('/hits/hits/0/_source/release'));
732
  });
733
  say $cv->recv;
734

            
735
You could for example just embed the built-in web server into an L<AnyEvent>
736
application.
737

            
738
  use Mojolicious::Lite;
739
  use Mojo::Server::Daemon;
740
  use EV;
741
  use AnyEvent;
742

            
743
  # Normal action
744
  get '/' => {text => 'Hello World!'};
745

            
746
  # Connect application with web server and start accepting connections
747
  my $daemon
748
    = Mojo::Server::Daemon->new(app => app, listen => ['http://*:8080']);
749
  $daemon->start;
750

            
751
  # Let AnyEvent take control
752
  AE::cv->recv;
753

            
754
=head1 USER AGENT
755

            
756
When we say L<Mojolicious> is a web framework we actually mean it.
757

            
758
=head2 Web scraping
759

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

            
766
  use Mojo::UserAgent;
767

            
768
  # Fetch web site
769
  my $ua = Mojo::UserAgent->new;
770
  my $tx = $ua->get('mojolicio.us/perldoc');
771

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

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

            
778
  # Visit all elements recursively to extract more than just text
779
  for my $e ($tx->res->dom('*')->each) {
780

            
781
    # Text before this element
782
    print $e->text_before(0);
783

            
784
    # Also include alternate text for images
785
    print $e->{alt} if $e->type eq 'img';
786

            
787
    # Text for elements without children
788
    print $e->text(0) unless $e->children->size;
789

            
790
    # Text after last element
791
    print $e->text_after(0) unless $e->next;
792
  }
793

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

            
796
=head2 JSON web services
797

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

            
803
  use Mojo::UserAgent;
804
  use Mojo::URL;
805

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

            
809
  # Search MetaCPAN for "mojolicious" and list latest releases
810
  my $url = Mojo::URL->new('http://api.metacpan.org/v0/release/_search');
811
  $url->query({q => 'mojolicious', sort => 'date:desc'});
812
  for my $hit (@{$ua->get($url)->res->json->{hits}{hits}}) {
813
    say "$hit->{_source}{name} ($hit->{_source}{author})";
814
  }
815

            
816
=head2 Basic authentication
817

            
818
You can just add username and password to the URL.
819

            
820
  use Mojo::UserAgent;
821

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

            
825
=head2 Decorating followup requests
826

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

            
832
  use Mojo::UserAgent;
833

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

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

            
844
  # Request that will most likely get redirected
845
  say 'Title: ', $ua->get('google.com')->res->dom->at('head > title')->text;
846

            
847
This even works for proxy C<CONNECT> requests.
848

            
849
=head2 Content generators
850

            
851
Content generators can be registered with
852
L<Mojo::UserAgent::Transactor/"add_generator"> to generate the same type of
853
content repeatedly for multiple requests.
854

            
855
  use Mojo::UserAgent;
856
  use Mojo::Asset::File;
857

            
858
  # Add "stream" generator
859
  my $ua = Mojo::UserAgent->new;
860
  $ua->transactor->add_generator(stream => sub {
861
    my ($transactor, $tx, $path) = @_;
862
    $tx->req->content->asset(Mojo::Asset::File->new(path => $path));
863
  });
864

            
865
  # Send multiple files streaming via PUT and POST
866
  $ua->put('http://example.com/upload'  => stream => '/home/sri/mojo.png');
867
  $ua->post('http://example.com/upload' => stream => '/home/sri/mango.png');
868

            
869
The C<json> and C<form> content generators are always available.
870

            
871
  use Mojo::UserAgent;
872

            
873
  # Send "application/json" content via PATCH
874
  my $ua = Mojo::UserAgent->new;
875
  my $tx = $ua->patch('http://api.example.com' => json => {foo => 'bar'});
876

            
877
  # Send query parameters via GET
878
  my $tx2 = $ua->get('http://search.example.com' => form => {q => 'test'});
879

            
880
  # Send "application/x-www-form-urlencoded" content via POST
881
  my $tx3 = $ua->post('http://search.example.com' => form => {q => 'test'});
882

            
883
  # Send "multipart/form-data" content via PUT
884
  my $tx4 = $ua->put('http://upload.example.com' =>
885
    form => {test => {content => 'Hello World!'}});
886

            
887
For more information about available content generators see also
888
L<Mojo::UserAgent::Transactor/"tx">.
889

            
890
=head2 Large file downloads
891

            
892
When downloading large files with L<Mojo::UserAgent> you don't have to worry
893
about memory usage at all, because it will automatically stream everything
894
above C<250KB> into a temporary file, which can then be moved into a permanent
895
file with L<Mojo::Asset::File/"move_to">.
896

            
897
  use Mojo::UserAgent;
898

            
899
  # Lets fetch the latest Mojolicious tarball
900
  my $ua = Mojo::UserAgent->new(max_redirects => 5);
901
  my $tx = $ua->get('latest.mojolicio.us');
902
  $tx->res->content->asset->move_to('mojo.tar.gz');
903

            
904
To protect you from excessively large files there is also a limit of C<10MB>
905
by default, which you can tweak with the MOJO_MAX_MESSAGE_SIZE environment
906
variable.
907

            
908
  # Increase limit to 1GB
909
  $ENV{MOJO_MAX_MESSAGE_SIZE} = 1073741824;
910

            
911
=head2 Large file upload
912

            
913
Uploading a large file is even easier.
914

            
915
  use Mojo::UserAgent;
916

            
917
  # Upload file via POST and "multipart/form-data"
918
  my $ua = Mojo::UserAgent->new;
919
  $ua->post('example.com/upload' =>
920
    form => {image => {file => '/home/sri/hello.png'}});
921

            
922
And once again you don't have to worry about memory usage, all data will be
923
streamed directly from the file.
924

            
925
=head2 Streaming response
926

            
927
Receiving a streaming response can be really tricky in most HTTP clients, but
928
L<Mojo::UserAgent> makes it actually easy.
929

            
930
  use Mojo::UserAgent;
931

            
932
  # Build a normal transaction
933
  my $ua = Mojo::UserAgent->new;
934
  my $tx = $ua->build_tx(GET => 'http://example.com');
935

            
936
  # Accept response of indefinite size
937
  $tx->res->max_message_size(0);
938

            
939
  # Replace "read" events to disable default content parser
940
  $tx->res->content->unsubscribe('read')->on(read => sub {
941
    my ($content, $bytes) = @_;
942
    say "Streaming: $bytes";
943
  });
944

            
945
  # Process transaction
946
  $ua->start($tx);
947

            
948
The event L<Mojo::Content/"read"> will be emitted for every chunk of data that
949
is received, even C<chunked> encoding will be handled transparently if
950
necessary.
951

            
952
=head2 Streaming request
953

            
954
Sending a streaming request is almost just as easy.
955

            
956
  use Mojo::UserAgent;
957

            
958
  # Build a normal transaction
959
  my $ua = Mojo::UserAgent->new;
960
  my $tx = $ua->build_tx(GET => 'http://example.com');
961

            
962
  # Prepare body
963
  my $body = 'Hello world!';
964
  $tx->req->headers->content_length(length $body);
965

            
966
  # Start writing directly with a drain callback
967
  my $drain;
968
  $drain = sub {
969
    my $content = shift;
970
    my $chunk   = substr $body, 0, 1, '';
971
    $drain      = undef unless length $body;
972
    $content->write($chunk, $drain);
973
  };
974
  $tx->req->content->$drain;
975

            
976
  # Process transaction
977
  $ua->start($tx);
978

            
979
The drain callback passed to L<Mojo::Content/"write"> will be invoked whenever
980
the entire previous chunk has actually been written.
981

            
982
=head2 Non-blocking
983

            
984
L<Mojo::UserAgent> has been designed from the ground up to be non-blocking,
985
the whole blocking API is just a simple convenience wrapper. Especially for
986
high latency tasks like web crawling this can be extremely useful, because you
987
can keep many parallel connections active at the same time.
988

            
989
  use Mojo::UserAgent;
990
  use Mojo::IOLoop;
991

            
992
  # Parallel non-blocking requests
993
  my $ua = Mojo::UserAgent->new;
994
  $ua->get('http://metacpan.org/search?q=mojo' => sub {
995
    my ($ua, $mojo) = @_;
996
    ...
997
  });
998
  $ua->get('http://metacpan.org/search?q=mango' => sub {
999
    my ($ua, $mango) = @_;
1000
    ...
1001
  });
1002

            
1003
  # Start event loop if necessary
1004
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
1005

            
1006
You can take full control of the L<Mojo::IOLoop> event loop.
1007

            
1008
=head2 Parallel blocking requests
1009

            
1010
You can emulate blocking behavior by using L<Mojo::IOLoop/"delay"> to
1011
synchronize multiple non-blocking requests.
1012

            
1013
  use Mojo::UserAgent;
1014
  use Mojo::IOLoop;
1015

            
1016
  # Synchronize non-blocking requests and capture results
1017
  my $ua    = Mojo::UserAgent->new;
1018
  my $delay = Mojo::IOLoop->delay;
1019
  $ua->get('http://metacpan.org/search?q=mojo'  => $delay->begin);
1020
  $ua->get('http://metacpan.org/search?q=mango' => $delay->begin);
1021
  my ($mojo, $mango) = $delay->wait;
1022

            
1023
The event L<Mojo::IOLoop::Delay/"finish"> can be used for code that needs to
1024
be able to work standalone as well as inside an already running event loop.
1025

            
1026
  use Mojo::UserAgent;
1027
  use Mojo::IOLoop;
1028

            
1029
  # Synchronize non-blocking requests portably
1030
  my $ua    = Mojo::UserAgent->new;
1031
  my $delay = Mojo::IOLoop->delay;
1032
  $delay->on(finish => sub {
1033
    my ($delay, $mojo, $mango) = @_;
1034
    ...
1035
  });
1036
  $ua->get('http://metacpan.org/search?q=mojo'  => $delay->begin);
1037
  $ua->get('http://metacpan.org/search?q=mango' => $delay->begin);
1038
  $delay->wait unless Mojo::IOLoop->is_running;
1039

            
1040
=head2 Command line
1041

            
1042
Don't you hate checking huge HTML files from the command line? Thanks to the
1043
C<mojo get> command that is about to change. You can just pick the parts that
1044
actually matter with the CSS selectors from L<Mojo::DOM> and JSON Pointers
1045
from L<Mojo::JSON::Pointer>.
1046

            
1047
  $ mojo get http://mojolicio.us 'head > title'
1048

            
1049
How about a list of all id attributes?
1050

            
1051
  $ mojo get http://mojolicio.us '*' attr id
1052

            
1053
Or the text content of all heading tags?
1054

            
1055
  $ mojo get http://mojolicio.us 'h1, h2, h3' text
1056

            
1057
Maybe just the text of the third heading?
1058

            
1059
  $ mojo get http://mojolicio.us 'h1, h2, h3' 3 text
1060

            
1061
You can also extract all text from nested child elements.
1062

            
1063
  $ mojo get http://mojolicio.us '#mojobar' all
1064

            
1065
The request can be customized as well.
1066

            
1067
  $ mojo get -M POST -c 'Hello!' http://mojolicio.us
1068
  $ mojo get -H 'X-Bender: Bite my shiny metal ass!' http://google.com
1069

            
1070
You can follow redirects and view the headers for all messages.
1071

            
1072
  $ mojo get -r -v http://google.com 'head > title'
1073

            
1074
Extract just the information you really need from JSON data structures.
1075

            
1076
  $ mojo get https://api.metacpan.org/v0/author/SRI /name
1077

            
1078
This can be an invaluable tool for testing your applications.
1079

            
1080
  $ ./myapp.pl get /welcome 'head > title'
1081

            
1082
=head2 One-liners
1083

            
1084
For quick hacks and especially testing, L<ojo> one-liners are also a great
1085
choice.
1086

            
1087
  $ perl -Mojo -E 'say g("mojolicio.us")->dom->html->head->title->text'
1088

            
1089
=head1 HACKS
1090

            
1091
Fun hacks you might not use very often but that might come in handy some day.
1092

            
1093
=head2 Adding commands to Mojolicious
1094

            
1095
By now you've probably used many of the built-in commands described in
1096
L<Mojolicious::Commands>, but did you know that you can just add new ones and
1097
that they will be picked up automatically by the command line interface?
1098

            
1099
  package Mojolicious::Command::spy;
1100
  use Mojo::Base 'Mojolicious::Command';
1101

            
1102
  has description => "Spy on application.\n";
1103
  has usage       => "usage: $0 spy [TARGET]\n";
1104

            
1105
  sub run {
1106
    my ($self, $target) = @_;
1107

            
1108
    # Leak secret passphrase
1109
    if ($target eq 'secret') {
1110
      my $secret = $self->app->secret;
1111
      say qq{The secret of this application is "$secret".};
1112
    }
1113
  }
1114

            
1115
  1;
1116

            
1117
There are many more useful attributes and methods in L<Mojolicious::Command>
1118
that you can use or overload.
1119

            
1120
  $ mojo spy secret
1121
  The secret of this application is "HelloWorld".
1122

            
1123
  $ ./myapp.pl spy secret
1124
  The secret of this application is "secr3t".
1125

            
1126
And to make your commands application specific, just put them in a different
1127
namespace.
1128

            
1129
  # Application
1130
  package MyApp;
1131
  use Mojo::Base 'Mojolicious';
1132

            
1133
  sub startup {
1134
    my $self = shift;
1135

            
1136
    # Add another namespace to load commands from
1137
    push @{$self->commands->namespaces}, 'MyApp::Command';
1138
  }
1139

            
1140
  1;
1141

            
1142
=head2 Running code against your application
1143

            
1144
Ever thought about running a quick one-liner against your L<Mojolicious>
1145
application to test something? Thanks to the C<eval> command you can do just
1146
that, the application object itself can be accessed via C<app>.
1147

            
1148
  $ mojo generate lite_app myapp.pl
1149
  $ ./myapp.pl eval 'say for @{app->static->paths}'
1150

            
1151
The C<verbose> options will automatically print the return value or returned
1152
data structure to C<STDOUT>.
1153

            
1154
  $ ./myapp.pl eval -v 'app->static->paths->[0]'
1155
  $ ./myapp.pl eval -V 'app->static->paths'
1156

            
1157
=head2 Making your application installable
1158

            
1159
Ever thought about releasing your L<Mojolicious> application to CPAN? It's
1160
actually much easier than you might think.
1161

            
1162
  $ mojo generate app MyApp
1163
  $ cd my_app
1164
  $ mv public lib/MyApp/
1165
  $ mv templates lib/MyApp/
1166

            
1167
The trick is to move the C<public> and C<templates> directories so they can
1168
get automatically installed with the modules.
1169

            
1170
  # Application
1171
  package MyApp;
1172
  use Mojo::Base 'Mojolicious';
1173

            
1174
  use File::Basename 'dirname';
1175
  use File::Spec::Functions 'catdir';
1176

            
1177
  # Every CPAN module needs a version
1178
  our $VERSION = '1.0';
1179

            
1180
  sub startup {
1181
    my $self = shift;
1182

            
1183
    # Switch to installable home directory
1184
    $self->home->parse(catdir(dirname(__FILE__), 'MyApp'));
1185

            
1186
    # Switch to installable "public" directory
1187
    $self->static->paths->[0] = $self->home->rel_dir('public');
1188

            
1189
    # Switch to installable "templates" directory
1190
    $self->renderer->paths->[0] = $self->home->rel_dir('templates');
1191

            
1192
    $self->plugin('PODRenderer');
1193

            
1194
    my $r = $self->routes;
1195
    $r->get('/welcome')->to('example#welcome');
1196
  }
1197

            
1198
  1;
1199

            
1200
That's really everything, now you can package your application like any other
1201
CPAN module.
1202

            
1203
  $ ./script/my_app generate makefile
1204
  $ perl Makefile.PL
1205
  $ make test
1206
  $ make manifest
1207
  $ make dist
1208

            
1209
And if you have a C<PAUSE> account (which can be requested at
1210
L<http://pause.perl.org>) even upload it.
1211

            
1212
  $ mojo cpanify -u USER -p PASS MyApp-0.01.tar.gz
1213

            
1214
=head2 Hello World
1215

            
1216
If every byte matters this is the smallest C<Hello World> application you can
1217
write with L<Mojolicious::Lite>.
1218

            
1219
  use Mojolicious::Lite;
1220
  any {text => 'Hello World!'};
1221
  app->start;
1222

            
1223
It works because all routes without a pattern default to C</> and automatic
1224
rendering kicks in even if no actual code gets executed by the router. The
1225
renderer just picks up the C<text> value from the stash and generates a
1226
response.
1227

            
1228
=head2 Hello World one-liners
1229

            
1230
The C<Hello World> example above can get even a little bit shorter in an
1231
L<ojo> one-liner.
1232

            
1233
  $ perl -Mojo -E 'a({text => "Hello World!"})->start' daemon
1234

            
1235
And you can use all the commands from L<Mojolicious::Commands>.
1236

            
1237
  $ perl -Mojo -E 'a({text => "Hello World!"})->start' get -v /
1238

            
1239
=head1 MORE
1240

            
1241
You can continue with L<Mojolicious::Guides> now or take a look at the
1242
L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
1243
more documentation and examples by many different authors.
1244

            
1245
=head1 SUPPORT
1246

            
1247
If you have any questions the documentation might not yet answer, don't
1248
hesitate to ask on the
1249
L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
1250
channel C<#mojo> on C<irc.perl.org>.
1251

            
1252
=cut