1Mojolicious::Guides::CoUoskebrooCko(n3t)ributed Perl DocMuomjeonltiactiioouns::Guides::Cookbook(3)
2
3
4

NAME

6       Mojolicious::Guides::Cookbook - Cooking with Mojolicious
7

OVERVIEW

9       This document contains many fun recipes for cooking with Mojolicious.
10

CONCEPTS

12       Essentials every Mojolicious developer should know.
13
14   Blocking and non-blocking operations
15       A blocking operation is a subroutine that blocks the execution of the
16       calling subroutine until the subroutine is finished.
17
18         sub foo {
19           my $result = blocking_subroutine();
20           ...
21         }
22
23       A non-blocking operation on the other hand lets the calling subroutine
24       continue execution even though the subroutine is not yet finished.
25       Instead of waiting, the calling subroutine passes along a callback to
26       be executed once the subroutine is finished, this is called
27       continuation-passing style.
28
29         sub foo {
30           non_blocking_subroutine(sub ($result) {
31             ...
32           });
33           ...
34         }
35
36       While Mojolicious has been designed from the ground up for non-blocking
37       I/O and event loops, it is not possible to magically make Perl code
38       non-blocking. You have to use specialized non-blocking code available
39       through modules like Mojo::IOLoop and Mojo::UserAgent, or third-party
40       event loops. You can wrap your blocking code in subprocesses though to
41       prevent it from interfering with your non-blocking code.
42
43   Event loops
44       An event loop is basically a loop that continually tests for external
45       events and executes the appropriate callbacks to handle them, it is
46       often the main loop in a program. Non-blocking tests for
47       readability/writability of file descriptors and timers are commonly
48       used events for highly scalable network servers, because they allow a
49       single process to handle thousands of client connections concurrently.
50
51         while (1) {
52           my @readable = test_fds_for_readability();
53           handle_readable_fds(@readable);
54
55           my @writable = test_fds_for_writability();
56           handle_writable_fds(@writable);
57
58           my @expired = test_timers();
59           handle_timers(@expired);
60         }
61
62       In Mojolicious this event loop is Mojo::IOLoop.
63
64   Reverse proxy
65       A reverse proxy architecture is a deployment technique used in many
66       production environments, where a reverse proxy server is put in front
67       of your application to act as the endpoint accessible by external
68       clients. It can provide a lot of benefits, like terminating SSL
69       connections from the outside, limiting the number of concurrent open
70       sockets towards the Mojolicious application (or even using Unix
71       sockets), balancing load across multiple instances, or supporting
72       several applications through the same IP/port.
73
74                          ..........................................
75                          :                                        :
76          +--------+      :  +-----------+      +---------------+  :
77          |        |-------->|           |      |               |  :
78          | client |      :  |  reverse  |----->|  Mojolicious  |  :
79          |        |<--------|   proxy   |      |  application  |  :
80          +--------+      :  |           |<-----|               |  :
81                          :  +-----------+      +---------------+  :
82                          :                                        :
83                          .. system boundary (e.g. same host) ......
84
85       This setup introduces some problems, though: the application will
86       receive requests from the reverse proxy instead of the original client;
87       the address/hostname where your application lives internally will be
88       different from the one visible from the outside; and if terminating
89       SSL, the reverse proxy exposes services via HTTPS while using HTTP
90       towards the Mojolicious application.
91
92       As an example, compare a sample request from the client and what the
93       Mojolicious application receives:
94
95          client                       reverse proxy                Mojolicious app
96           __|__              _______________|______________             ____|____
97          /     \            /                              \           /         \
98          1.2.3.4 --HTTPS--> api.example.com      10.20.30.39 --HTTP--> 10.20.30.40
99
100          GET /foo/1 HTTP/1.1                |    GET /foo/1 HTTP/1.1
101          Host: api.example.com              |    Host: 10.20.30.40
102          User-Agent: Firefox                |    User-Agent: ShinyProxy/1.2
103          ...                                |    ...
104
105       However, now the client address is no longer available (which might be
106       useful for analytics, or Geo-IP) and URLs generated via "url_for" in
107       Mojolicious::Controller will look like this:
108
109          http://10.20.30.40/bar/2
110
111       instead of something meaningful for the client, like this:
112
113          https://api.example.com/bar/2
114
115       To solve these problems, you can configure your reverse proxy to send
116       the missing data (see "Nginx" and "Apache/mod_proxy") and tell your
117       application about it by setting the environment variable
118       "MOJO_REVERSE_PROXY".  In more complex situations, usually involving
119       multiple proxies or proxies that live outside your network, it can be
120       necessary to tell the application from which ip addresses to expect
121       proxy requests by setting "MOJO_TRUSTED_PROXIES" to a list of comma
122       separated addresses or CIDR networks. For even finer control,
123       "Rewriting" includes examples of how the changes could be implemented
124       manually.
125

DEPLOYMENT

127       Getting Mojolicious and Mojolicious::Lite applications running on
128       different platforms. Note that many real-time web features are based on
129       the Mojo::IOLoop event loop, and therefore require one of the built-in
130       web servers to be able to use them to their full potential.
131
132   Built-in web server
133       Mojolicious contains a very portable non-blocking I/O HTTP and
134       WebSocket server with Mojo::Server::Daemon. It is usually used during
135       development and in the construction of more advanced web servers, but
136       is solid and fast enough for small to mid sized applications.
137
138         $ ./script/my_app daemon
139         Web application available at http://127.0.0.1:3000
140
141       It is available to every application through the command
142       Mojolicious::Command::daemon, which has many configuration options and
143       is known to work on every platform Perl works on with its single-
144       process architecture.
145
146         $ ./script/my_app daemon -h
147         ...List of available options...
148
149       Another huge advantage is that it supports TLS and WebSockets out of
150       the box, a development certificate for testing purposes is built right
151       in, so it just works, but you can specify all listen locations
152       supported by "listen" in Mojo::Server::Daemon.
153
154         $ ./script/my_app daemon -l https://[::]:3000
155         Web application available at https://[::]:3000
156
157       To manage the web server with systemd, you can use a unit configuration
158       file like this.
159
160         [Unit]
161         Description=My Mojolicious application
162         After=network.target
163
164         [Service]
165         Type=simple
166         User=sri
167         ExecStart=/home/sri/myapp/script/my_app daemon -m production -l http://*:8080
168
169         [Install]
170         WantedBy=multi-user.target
171
172   Pre-forking
173       For bigger applications Mojolicious contains the UNIX optimized pre-
174       forking web server Mojo::Server::Prefork, which can take advantage of
175       multiple CPU cores and copy-on-write memory management to scale up to
176       thousands of concurrent client connections.
177
178         Mojo::Server::Prefork
179         |- Mojo::Server::Daemon [1]
180         |- Mojo::Server::Daemon [2]
181         |- Mojo::Server::Daemon [3]
182         +- Mojo::Server::Daemon [4]
183
184       It is based on Mojo::Server::Daemon and available to every application
185       through the command Mojolicious::Command::prefork.
186
187         $ ./script/my_app prefork
188         Web application available at http://127.0.0.1:3000
189
190       Since all built-in web servers are based on the Mojo::IOLoop event
191       loop, they scale best with non-blocking operations. But if your
192       application for some reason needs to perform many blocking operations,
193       you can improve performance by increasing the number of worker
194       processes and decreasing the number of concurrent connections each
195       worker is allowed to handle (often as low as 1).
196
197         $ ./script/my_app prefork -m production -w 10 -c 1
198         Web application available at http://127.0.0.1:3000
199
200       During startup your application is preloaded in the manager process,
201       which does not run an event loop, so you can use "next_tick" in
202       Mojo::IOLoop to run code whenever a new worker process has been forked
203       and its event loop gets started.
204
205         use Mojolicious::Lite;
206
207         Mojo::IOLoop->next_tick(sub ($ioloop) {
208           app->log->info("Worker $$ star...ALL GLORY TO THE HYPNOTOAD!");
209         });
210
211         get '/' => {text => 'Hello Wor...ALL GLORY TO THE HYPNOTOAD!'};
212
213         app->start;
214
215       And to manage the pre-forking web server with systemd, you can use a
216       unit configuration file like this.
217
218         [Unit]
219         Description=My Mojolicious application
220         After=network.target
221
222         [Service]
223         Type=simple
224         User=sri
225         ExecStart=/home/sri/myapp/script/my_app prefork -m production -l http://*:8080
226
227         [Install]
228         WantedBy=multi-user.target
229
230   Morbo
231       After reading the Mojolicious::Guides::Tutorial, you should already be
232       familiar with Mojo::Server::Morbo.
233
234         Mojo::Server::Morbo
235         +- Mojo::Server::Daemon
236
237       It is basically a restarter that forks a new Mojo::Server::Daemon web
238       server whenever a file in your project changes, and should therefore
239       only be used during development. To start applications with it you can
240       use the morbo script.
241
242         $ morbo ./script/my_app
243         Web application available at http://127.0.0.1:3000
244
245   Containers
246       There are many ways to go cloud-native with Mojolicious. To get you
247       started with containerizing your web applications we will explore one
248       of them in this recipe. First, you will need to declare the CPAN
249       dependencies of your application, for example in a "Makefile.PL" file.
250       This should always include at the very least Mojolicious itself.
251
252         use strict;
253         use warnings;
254
255         use ExtUtils::MakeMaker;
256
257         WriteMakefile(
258           VERSION   => '0.01',
259           PREREQ_PM => {
260             'Mojolicious' => '8.65',
261             'Mojolicious::Plugin::Status' => '1.12'
262           },
263           test => {TESTS => 't/*.t'}
264         );
265
266       The helper command Mojolicious::Command::Author::generate::makefile can
267       also generate a minimal "Makefile.PL" for you.
268
269         $ ./myapp.pl generate makefile
270         ...
271
272       And then we are going to need a "Dockerfile" describing the container.
273       A very simple one will do for now.
274
275         FROM perl
276         WORKDIR /opt/myapp
277         COPY . .
278         RUN cpanm --installdeps -n .
279         EXPOSE 3000
280         CMD ./myapp.pl prefork
281
282       It uses the latest Perl container <https://hub.docker.com/_/perl> from
283       Docker Hub, copies all the contents of your application directory into
284       the container, installs CPAN dependencies with App::cpanminus, and then
285       starts the application on port 3000 with the pre-forking web server.
286       With Mojolicious::Command::Author::generate::dockerfile there is also a
287       helper command to generate a minimal "Dockerfile" for you.
288
289         $ ./myapp.pl generate dockerfile
290         ...
291
292       To build and deploy our container there are also many options
293       available, here we will simply use Docker.
294
295         $ docker build -t myapp_image .
296         ...
297         $ docker run -d -p 3000:3000 --name myapp_container myapp_image
298         ...
299
300       And now your web application should be deployed as a container under
301       "http://127.0.0.1:3000". For more information and many more container
302       deployment options we recommend the Docker <https://docs.docker.com/>
303       and Kubernetes <https://kubernetes.io/docs/> documentation.
304
305   Hypnotoad
306       Hypnotoad is based on the Mojo::Server::Prefork web server, and adds
307       some features especially optimized for high availability non-
308       containerized production environments. To start applications with it
309       you can use the hypnotoad script, which listens on port 8080,
310       automatically daemonizes the server process and defaults to
311       "production" mode for Mojolicious and Mojolicious::Lite applications.
312
313         $ hypnotoad ./script/my_app
314
315       Many configuration settings can be tweaked right from within your
316       application with "config" in Mojolicious, for a full list see
317       "SETTINGS" in Mojo::Server::Hypnotoad.
318
319         use Mojolicious::Lite;
320
321         app->config(hypnotoad => {listen => ['http://*:80']});
322
323         get '/' => {text => 'Hello Wor...ALL GLORY TO THE HYPNOTOAD!'};
324
325         app->start;
326
327       Or just add a "hypnotoad" section to your Mojolicious::Plugin::Config,
328       Mojolicious::Plugin::JSONConfig or Mojolicious::Plugin::NotYAMLConfig
329       configuration file.
330
331         # myapp.conf
332         {
333           hypnotoad => {
334             listen  => ['https://*:443?cert=/etc/server.crt&key=/etc/server.key'],
335             workers => 10
336           }
337         };
338
339       But one of its biggest advantages is the support for effortless zero
340       downtime software upgrades (hot deployment). That means you can upgrade
341       Mojolicious, Perl or even system libraries at runtime without ever
342       stopping the server or losing a single incoming connection, just by
343       running the command above again.
344
345         $ hypnotoad ./script/my_app
346         Starting hot deployment for Hypnotoad server 31841.
347
348       You might also want to enable proxy support if you're using Hypnotoad
349       behind a reverse proxy. This allows Mojolicious to automatically pick
350       up the "X-Forwarded-For" and "X-Forwarded-Proto" headers.
351
352         # myapp.conf
353         {hypnotoad => {proxy => 1}};
354
355       To manage Hypnotoad with systemd, you can use a unit configuration file
356       like this.
357
358         [Unit]
359         Description=My Mojolicious application
360         After=network.target
361
362         [Service]
363         Type=forking
364         User=sri
365         PIDFile=/home/sri/myapp/script/hypnotoad.pid
366         ExecStart=/path/to/hypnotoad /home/sri/myapp/script/my_app
367         ExecReload=/path/to/hypnotoad /home/sri/myapp/script/my_app
368         KillMode=process
369
370         [Install]
371         WantedBy=multi-user.target
372
373   Zero downtime software upgrades
374       Hypnotoad makes zero downtime software upgrades (hot deployment) very
375       simple, as you can see above, but on modern operating systems that
376       support the "SO_REUSEPORT" socket option, there is also another method
377       available that works with all built-in web servers.
378
379         $ ./script/my_app prefork -P /tmp/first.pid -l http://*:8080?reuse=1
380         Web application available at http://127.0.0.1:8080
381
382       All you have to do, is to start a second web server listening to the
383       same port, and stop the first web server gracefully afterwards.
384
385         $ ./script/my_app prefork -P /tmp/second.pid -l http://*:8080?reuse=1
386         Web application available at http://127.0.0.1:8080
387         $ kill -s TERM `cat /tmp/first.pid`
388
389       Just remember that both web servers need to be started with the "reuse"
390       parameter.
391
392   Nginx
393       One of the most popular setups these days is Hypnotoad behind an Nginx
394       <https://nginx.org> reverse proxy, which even supports WebSockets in
395       newer versions.
396
397         upstream myapp {
398           server 127.0.0.1:8080;
399         }
400         server {
401           listen 80;
402           server_name localhost;
403           location / {
404             proxy_pass http://myapp;
405             proxy_http_version 1.1;
406             proxy_set_header Upgrade $http_upgrade;
407             proxy_set_header Connection "upgrade";
408             proxy_set_header Host $host;
409             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
410             proxy_set_header X-Forwarded-Proto $scheme;
411           }
412         }
413
414   Apache/mod_proxy
415       Another good reverse proxy is Apache <https://httpd.apache.org> with
416       "mod_proxy", the configuration looks quite similar to the Nginx one
417       above. And if you need WebSocket support, newer versions come with
418       "mod_proxy_wstunnel".
419
420         <VirtualHost *:80>
421           ServerName localhost
422           <Proxy *>
423             Require all granted
424           </Proxy>
425           ProxyRequests Off
426           ProxyPreserveHost On
427           ProxyPass /echo ws://localhost:8080/echo
428           ProxyPass / http://localhost:8080/ keepalive=On
429           ProxyPassReverse / http://localhost:8080/
430           RequestHeader set X-Forwarded-Proto "http"
431         </VirtualHost>
432
433   Apache/CGI
434       "CGI" is supported out of the box and your Mojolicious application will
435       automatically detect that it is executed as a "CGI" script. Its use in
436       production environments is discouraged though, because as a result of
437       how "CGI" works, it is very slow and many web servers are making it
438       exceptionally hard to configure properly. Additionally, many real-time
439       web features, such as WebSockets, are not available.
440
441         ScriptAlias / /home/sri/my_app/script/my_app/
442
443   Envoy
444       Mojolicious applications can be deployed on cloud-native environments
445       that use Envoy <https://www.envoyproxy.io>, such as with this reverse
446       proxy configuration similar to the Apache and Nginx ones above.
447
448         static_resources:
449           listeners:
450           - name: listener_0
451             address:
452               socket_address: { address: 0.0.0.0, port_value: 80 }
453             filter_chains:
454             - filters:
455               - name: envoy.filters.network.http_connection_manager
456                 typed_config:
457                   "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
458                   codec_type: auto
459                   stat_prefix: index_http
460                   route_config:
461                     name: local_route
462                     virtual_hosts:
463                     - name: service
464                       domains: ["*"]
465                       routes:
466                       - match:
467                           prefix: "/"
468                         route:
469                           cluster: local_service
470                   upgrade_configs:
471                   - upgrade_type: websocket
472                   http_filters:
473                   - name: envoy.filters.http.router
474                     typed_config:
475           clusters:
476           - name: local_service
477             connect_timeout: 0.25s
478             type: strict_dns
479             lb_policy: round_robin
480             load_assignment:
481               cluster_name: local_service
482               endpoints:
483               - lb_endpoints:
484                 - endpoint:
485                     address:
486                       socket_address: { address: mojo, port_value: 8080 }
487
488       While this configuration works for simple applications, Envoy's typical
489       use case is for implementing proxies of applications as a "service
490       mesh" providing advanced filtering, load balancing, and observability
491       features, such as seen in Istio
492       <https://istio.io/latest/docs/ops/deployment/architecture/>. For more
493       examples, visit the Envoy documentation
494       <https://www.envoyproxy.io/docs/envoy/latest/start/start>.
495
496   PSGI/Plack
497       PSGI is an interface between Perl web frameworks and web servers, and
498       Plack is a Perl module and toolkit that contains PSGI middleware,
499       helpers and adapters to web servers. PSGI and Plack are inspired by
500       Python's WSGI and Ruby's Rack. Mojolicious applications are
501       ridiculously simple to deploy with Plack, but be aware that many real-
502       time web features, such as WebSockets, are not available.
503
504         $ plackup ./script/my_app
505
506       Plack provides many server and protocol adapters for you to choose
507       from, such as "FCGI", "uWSGI" and "mod_perl".
508
509         $ plackup ./script/my_app -s FCGI -l /tmp/myapp.sock
510
511       The "MOJO_REVERSE_PROXY" environment variable can be used to enable
512       proxy support, this allows Mojolicious to automatically pick up the
513       "X-Forwarded-For" and "X-Forwarded-Proto" headers.
514
515         $ MOJO_REVERSE_PROXY=1 plackup ./script/my_app
516
517       If an older server adapter is unable to correctly detect the
518       application home directory, you can simply use the "MOJO_HOME"
519       environment variable.
520
521         $ MOJO_HOME=/home/sri/my_app plackup ./script/my_app
522
523       There is no need for a ".psgi" file, just point the server adapter at
524       your application script, it will automatically act like one if it
525       detects the presence of a "PLACK_ENV" environment variable.
526
527   Plack middleware
528       Wrapper scripts like "myapp.fcgi" are a great way to separate
529       deployment and application logic.
530
531         #!/usr/bin/env plackup -s FCGI
532         use Plack::Builder;
533
534         builder {
535           enable 'Deflater';
536           require './script/my_app';
537         };
538
539       Mojo::Server::PSGI can be used directly to load and customize
540       applications in the wrapper script.
541
542         #!/usr/bin/env plackup -s FCGI
543         use Mojo::Server::PSGI;
544         use Plack::Builder;
545
546         builder {
547           enable 'Deflater';
548           my $server = Mojo::Server::PSGI->new;
549           $server->load_app('./script/my_app');
550           $server->app->config(foo => 'bar');
551           $server->to_psgi_app;
552         };
553
554       But you could even use middleware right in your application.
555
556         use Mojolicious::Lite -signatures;
557         use Plack::Builder;
558
559         get '/welcome' => sub ($c) {
560           $c->render(text => 'Hello Mojo!');
561         };
562
563         builder {
564           enable 'Deflater';
565           app->start;
566         };
567
568   Rewriting
569       Sometimes you might have to deploy your application in a blackbox
570       environment where you can't just change the server configuration or
571       behind a reverse proxy that passes along additional information with
572       "X-Forwarded-*" headers. In such cases you can use the hook
573       "before_dispatch" in Mojolicious to rewrite incoming requests.
574
575         # Change scheme if "X-Forwarded-HTTPS" header is set
576         $app->hook(before_dispatch => sub ($c) {
577           $c->req->url->base->scheme('https')
578             if $c->req->headers->header('X-Forwarded-HTTPS');
579         });
580
581       Since reverse proxies generally don't pass along information about path
582       prefixes your application might be deployed under, rewriting the base
583       path of incoming requests is also quite common. This allows "url_for"
584       in Mojolicious::Controller for example, to generate portable URLs based
585       on the current environment.
586
587         # Move first part and slash from path to base path in production mode
588         $app->hook(before_dispatch => sub ($c) {
589           push @{$c->req->url->base->path->trailing_slash(1)},
590             shift @{$c->req->url->path->leading_slash(0)};
591         }) if $app->mode eq 'production';
592
593       Mojo::URL objects are very easy to manipulate, just make sure that the
594       URL ("foo/bar?baz=yada"), which represents the routing destination, is
595       always relative to the base URL ("http://example.com/myapp/"), which
596       represents the deployment location of your application.
597
598   Deployment specific plugins
599       Deployment specific 3rd party plugins such as
600       Mojolicious::Plugin::SetUserGroup do not need to be included in your
601       application code. They can also be loaded later on via the reserved
602       "plugins" value for Mojolicious applications that are using any one of
603       the built-in configuration plugins Mojolicious::Plugin::Config,
604       Mojolicious::Plugin::JSONConfig or Mojolicious::Plugin::NotYAMLConfig.
605
606         # myapp.conf
607         {
608           plugins => [
609             {SetUserGroup => {user => 'sri', group => 'staff'}}
610           ]
611         };
612
613   Application embedding
614       From time to time you might want to reuse parts of Mojolicious
615       applications like configuration files, database connection or helpers
616       for other scripts, with this little Mojo::Server based mock server you
617       can just embed them.
618
619         use Mojo::Server;
620
621         # Load application with mock server
622         my $server = Mojo::Server->new;
623         my $app = $server->load_app('./myapp.pl');
624
625         # Access fully initialized application
626         say for @{$app->static->paths};
627         say $app->config->{secret_identity};
628         say $app->dumper({just => 'a helper test'});
629         say $app->build_controller->render_to_string(template => 'foo');
630
631       The plugin Mojolicious::Plugin::Mount uses this functionality to allow
632       you to combine multiple applications into one and deploy them together.
633
634         use Mojolicious::Lite;
635
636         app->config(hypnotoad => {listen => ['http://*:80']});
637
638         plugin Mount => {'test1.example.com' => '/home/sri/myapp1.pl'};
639         plugin Mount => {'test2.example.com' => '/home/sri/myapp2.pl'};
640
641         app->start;
642
643   Web server embedding
644       You can also use "one_tick" in Mojo::IOLoop to embed the built-in web
645       server Mojo::Server::Daemon into alien environments like foreign event
646       loops that for some reason can't just be integrated with a new reactor
647       backend.
648
649         use Mojolicious::Lite;
650         use Mojo::IOLoop;
651         use Mojo::Server::Daemon;
652
653         # Normal action
654         get '/' => {text => 'Hello World!'};
655
656         # Connect application with web server and start accepting connections
657         my $daemon = Mojo::Server::Daemon->new(app => app, listen => ['http://*:8080']);
658         $daemon->start;
659
660         # Call "one_tick" repeatedly from the alien environment
661         Mojo::IOLoop->one_tick while 1;
662

REAL-TIME WEB

664       The real-time web is a collection of technologies that include Comet
665       (long polling), EventSource and WebSockets, which allow content to be
666       pushed to consumers with long-lived connections as soon as it is
667       generated, instead of relying on the more traditional pull model. All
668       built-in web servers use non-blocking I/O and are based on the
669       Mojo::IOLoop event loop, which provides many very powerful features
670       that allow real-time web applications to scale up to thousands of
671       concurrent client connections.
672
673   Backend web services
674       Since Mojo::UserAgent is also based on the Mojo::IOLoop event loop, it
675       won't block the built-in web servers when used non-blocking, even for
676       high latency backend web services.
677
678         use Mojolicious::Lite -signatures;
679
680         # Search MetaCPAN for "mojolicious"
681         get '/' => sub ($c) {
682           $c->ua->get('fastapi.metacpan.org/v1/module/_search?q=mojolicious' => sub ($ua, $tx) {
683             $c->render('metacpan', hits => $tx->result->json->{hits}{hits});
684           });
685         };
686
687         app->start;
688         __DATA__
689
690         @@ metacpan.html.ep
691         <!DOCTYPE html>
692         <html>
693           <head><title>MetaCPAN results for "mojolicious"</title></head>
694           <body>
695             % for my $hit (@$hits) {
696               <p><%= $hit->{_source}{release} %></p>
697             % }
698           </body>
699         </html>
700
701       The callback passed to "get" in Mojo::UserAgent will be executed once
702       the request to the backend web service has been finished, this is
703       called continuation-passing style.
704
705   Synchronizing non-blocking operations
706       Multiple non-blocking operations, such as concurrent requests, can be
707       easily synchronized with promises and "all" in Mojo::Promise. You
708       create Mojo::Promise objects manually or use methods like "get_p" in
709       Mojo::UserAgent that create them for you.
710
711         use Mojolicious::Lite -signatures;
712         use Mojo::Promise;
713         use Mojo::URL;
714
715         # Search MetaCPAN for "mojo" and "minion"
716         get '/' => sub ($c) {
717
718           # Create two promises
719           my $url   = Mojo::URL->new('http://fastapi.metacpan.org/v1/module/_search');
720           my $mojo   = $c->ua->get_p($url->clone->query({q => 'mojo'}));
721           my $minion = $c->ua->get_p($url->clone->query({q => 'minion'}));
722
723           # Render a response once both promises have been resolved
724           Mojo::Promise->all($mojo, $minion)->then(sub ($mojo, $minion) {
725             $c->render(json => {
726               mojo   => $mojo->[0]->result->json('/hits/hits/0/_source/release'),
727               minion => $minion->[0]->result->json('/hits/hits/0/_source/release')
728             });
729           })->catch(sub ($err) {
730             $c->reply->exception($err);
731           })->wait;
732         };
733
734         app->start;
735
736       To create promises manually you just wrap your continuation-passing
737       style APIs in functions that return promises.  Here's an example for
738       how "get_p" in Mojo::UserAgent works internally.
739
740         use Mojo::UserAgent;
741         use Mojo::Promise;
742
743         # Wrap a user agent method with a promise
744         my $ua = Mojo::UserAgent->new;
745         sub get_p {
746           my $promise = Mojo::Promise->new;
747           $ua->get(@_ => sub ($ua, $tx) {
748             my $err = $tx->error;
749             $promise->resolve($tx) if !$err || $err->{code};
750             $promise->reject($err->{message});
751           });
752           return $promise;
753         }
754
755         # Use our new promise generating function
756         get_p('https://mojolicious.org')->then(sub ($tx) {
757           say $tx->result->dom->at('title')->text;
758         })->wait;
759
760       Promises have three states, they start out as "pending" and you call
761       "resolve" in Mojo::Promise to transition them to "fulfilled", or
762       "reject" in Mojo::Promise to transition them to "rejected".
763
764   async/await
765       And if you have Future::AsyncAwait installed you can make using
766       promises even easier. The "async" and "await" keywords are enabled with
767       the "-async_await" flag of Mojo::Base, and make the use of closures
768       with promises completely optional.
769
770         use Mojo::Base -strict, -async_await;
771
772       The "async" keyword is placed before the "sub" keyword, and means that
773       this function always returns a promise.  Returned values that are not
774       Mojo::Promise objects will be wrapped in a resolved promise
775       automatically. And if an exception gets thrown in the function it will
776       result in a rejected promise.
777
778         use Mojo::Base -strict, -async_await;
779
780         async sub hello_p {
781           return 'Hello Mojo!';
782         }
783
784         hello_p()->then(sub { say @_ })->wait;
785
786       The "await" keyword on the other hand makes Perl wait for the promise
787       to be settled. It then returns the fulfillment values or throws an
788       exception with the rejection reason. While waiting, the event loop is
789       free to perform other tasks however, so no resources are wasted.
790
791         use Mojo::Base -strict, -signatures, -async_await;
792         use Mojo::UserAgent;
793         use Mojo::URL;
794
795         my $ua = Mojo::UserAgent->new;
796
797         # Search MetaCPAN non-blocking for multiple terms sequentially
798         async sub search_cpan_p ($terms) {
799           my $cpan = Mojo::URL->new('http://fastapi.metacpan.org/v1/module/_search');
800           my @urls = map { $cpan->clone->query(q => $_) } @$terms;
801
802           for my $url (@urls) {
803             my $tx = await $ua->get_p($url);
804             say $tx->result->json('/hits/hits/0/_source/release');
805           }
806         }
807
808         search_cpan_p(['mojo', 'minion'])->wait;
809
810       The loop above performs all requests sequentially, awaiting a result
811       before sending the next request. But you can also perform those
812       requests concurrently instead, by using methods like "all" in
813       Mojo::Promise to combine multiple promises before awaiting the results.
814
815         use Mojo::Base -strict, -signatures, -async_await;
816         use Mojo::Promise;
817         use Mojo::UserAgent;
818         use Mojo::URL;
819
820         my $ua = Mojo::UserAgent->new;
821
822         # Search MetaCPAN non-blocking for multiple terms concurrently
823         async sub search_cpan_p ($terms) {
824           my $cpan = Mojo::URL->new('http://fastapi.metacpan.org/v1/module/_search');
825           my @urls = map { $cpan->clone->query(q => $_) } @$terms;
826
827           my @promises = map { $ua->get_p($_) } @urls;
828           my @results  = await Mojo::Promise->all(@promises);
829           for my $result (@results) {
830             say $result->[0]->result->json('/hits/hits/0/_source/release');
831           }
832         }
833
834         search_cpan_p(['mojo', 'minion'])->wait;
835
836       All of this also means that you can use normal Perl exception handling
837       again. Even many 3rd party exception handling modules from CPAN work
838       just fine.
839
840         use Mojo::Base -strict, -async_await;
841         use Mojo::Promise;
842
843         # Catch a non-blocking exception
844         async sub hello_p {
845           eval { await Mojo::Promise->reject('This is an exception') };
846           if (my $err = $@) { warn "Error: $err" }
847         }
848
849         hello_p()->wait;
850
851       And it works just the same in Mojolicious and Mojolicious::Lite
852       applications. Just declare your actions with the "async" keyword and
853       use "await" to wait for promises to be "fulfilled" or "rejected".
854
855         use Mojolicious::Lite -signatures, -async_await;
856
857         # Request HTML titles from two sites non-blocking
858         get '/' => async sub ($c) {
859           my $mojo_tx    = await $c->ua->get_p('https://mojolicious.org');
860           my $mojo_title = $mojo_tx->result->dom->at('title')->text;
861           my $cpan_tx    = await $c->ua->get_p('https://metacpan.org');
862           my $cpan_title = $cpan_tx->result->dom->at('title')->text;
863
864           $c->render(json => {mojo => $mojo_title, cpan => $cpan_title});
865         };
866
867         app->start;
868
869       Promises returned by actions will automatically get the default
870       Mojolicious exception handler attached. Making it much harder to ever
871       miss a non-blocking exception again, even if you forgot to handle it
872       yourself.
873
874   Timers
875       Timers, another primary feature of the event loop, are created with
876       "timer" in Mojo::IOLoop and can, for example, be used to delay
877       rendering of a response, and unlike "sleep", won't block any other
878       requests that might be processed concurrently.
879
880         use Mojolicious::Lite -signatures;
881         use Mojo::IOLoop;
882
883         # Wait 3 seconds before rendering a response
884         get '/' => sub ($c) {
885           Mojo::IOLoop->timer(3 => sub ($ioloop) {
886             $c->render(text => 'Delayed by 3 seconds!');
887           });
888         };
889
890         app->start;
891
892       Recurring timers created with "recurring" in Mojo::IOLoop are slightly
893       more powerful, but need to be stopped manually, or they would just keep
894       getting emitted.
895
896         use Mojolicious::Lite -signatures;
897         use Mojo::IOLoop;
898
899         # Count to 5 in 1 second steps
900         get '/' => sub ($c) {
901
902           # Start recurring timer
903           my $i = 1;
904           my $id = Mojo::IOLoop->recurring(1 => sub ($ioloop) {
905             $c->write_chunk($i);
906             $c->finish if $i++ == 5;
907           });
908
909           # Stop recurring timer
910           $c->on(finish => sub ($c) { Mojo::IOLoop->remove($id) });
911         };
912
913         app->start;
914
915       Timers are not tied to a specific request or connection, and can even
916       be created at startup time.
917
918         use Mojolicious::Lite -signatures;
919         use Mojo::IOLoop;
920
921         # Check title in the background every 10 seconds
922         my $title = 'Got no title yet.';
923         Mojo::IOLoop->recurring(10 => sub ($ioloop) {
924           app->ua->get('https://mojolicious.org' => sub ($ua, $tx) {
925             $title = $tx->result->dom->at('title')->text;
926           });
927         });
928
929         # Show current title
930         get '/' => sub ($c) {
931           $c->render(json => {title => $title});
932         };
933
934         app->start;
935
936       Just remember that all these non-blocking operations are processed
937       cooperatively, so your callbacks shouldn't block for too long.
938
939   Subprocesses
940       You can also use subprocesses, created with "subprocess" in
941       Mojo::IOLoop, to perform computationally expensive operations without
942       blocking the event loop.
943
944         use Mojolicious::Lite -signatures;
945         use Mojo::IOLoop;
946
947         # Operation that would block the event loop for 5 seconds
948         get '/' => sub ($c) {
949           Mojo::IOLoop->subprocess->run_p(sub {
950             sleep 5;
951             return '♥', 'Mojolicious';
952           })->then(sub (@results) {
953             $c->render(text => "I $results[0] $results[1]!");
954           })->catch(sub ($err) {
955             $c->reply->exception($err);
956           });
957         };
958
959         app->start;
960
961       The callback passed to "run_p" in Mojo::IOLoop::Subprocess will be
962       executed in a child process, without blocking the event loop of the
963       parent process. The results of the callback will then be shared between
964       both processes, and the promise fulfilled or rejected in the parent
965       process.
966
967   Exceptions in non-blocking operations
968       Since timers and other non-blocking operations are running solely in
969       the event loop, outside of the application, exceptions that get thrown
970       in callbacks can't get caught and handled automatically. But you can
971       handle them manually by subscribing to the event "error" in
972       Mojo::Reactor or catching them inside the callback.
973
974         use Mojolicious::Lite -signatures;
975         use Mojo::IOLoop;
976
977         # Forward error messages to the application log
978         Mojo::IOLoop->singleton->reactor->on(error => sub ($reactor, $err) {
979           app->log->error($err);
980         });
981
982         # Exception only gets logged (and connection times out)
983         get '/connection_times_out' => sub ($c) {
984           Mojo::IOLoop->timer(2 => sub ($ioloop) {
985             die 'This request will not be getting a response';
986           });
987         };
988
989         # Exception gets caught and handled
990         get '/catch_exception' => sub ($c) {
991           Mojo::IOLoop->timer(2 => sub ($ioloop) {
992             eval { die 'This request will be getting a response' };
993             $c->reply->exception($@) if $@;
994           });
995         };
996
997         app->start;
998
999       A default subscriber that turns all errors into warnings will usually
1000       be added by Mojo::IOLoop as a fallback.
1001
1002         Mojo::IOLoop->singleton->reactor->unsubscribe('error');
1003
1004       During development or for applications where crashing is simply
1005       preferable, you can also make every exception that gets thrown in a
1006       callback fatal by removing all of its subscribers.
1007
1008   WebSocket web service
1009       The WebSocket protocol offers full bi-directional low-latency
1010       communication channels between clients and servers.  Receive messages
1011       just by subscribing to events such as "message" in
1012       Mojo::Transaction::WebSocket with "on" in Mojolicious::Controller and
1013       return them with "send" in Mojolicious::Controller.
1014
1015         use Mojolicious::Lite -signatures;
1016
1017         # Template with browser-side code
1018         get '/' => 'index';
1019
1020         # WebSocket echo service
1021         websocket '/echo' => sub ($c) {
1022
1023           # Opened
1024           $c->app->log->debug('WebSocket opened');
1025
1026           # Increase inactivity timeout for connection a bit
1027           $c->inactivity_timeout(300);
1028
1029           # Incoming message
1030           $c->on(message => sub ($c, $msg) {
1031             $c->send("echo: $msg");
1032           });
1033
1034           # Closed
1035           $c->on(finish => sub ($c, $code, $reason = undef) {
1036             $c->app->log->debug("WebSocket closed with status $code");
1037           });
1038         };
1039
1040         app->start;
1041         __DATA__
1042
1043         @@ index.html.ep
1044         <!DOCTYPE html>
1045         <html>
1046           <head><title>Echo</title></head>
1047           <body>
1048             <script>
1049               const ws = new WebSocket('<%= url_for('echo')->to_abs %>');
1050
1051               // Incoming messages
1052               ws.onmessage = function (event) {
1053                 document.body.innerHTML += event.data + '<br/>';
1054               };
1055
1056               // Outgoing messages
1057               ws.onopen = function (event) {
1058                 window.setInterval(function () { ws.send('Hello Mojo!') }, 1000);
1059               };
1060             </script>
1061           </body>
1062         </html>
1063
1064       The event "finish" in Mojo::Transaction::WebSocket will be emitted
1065       right after the WebSocket connection has been closed.
1066
1067         $c->tx->with_compression;
1068
1069       You can activate "permessage-deflate" compression with
1070       "with_compression" in Mojo::Transaction::WebSocket, this can result in
1071       much better performance, but also increases memory usage by up to
1072       300KiB per connection.
1073
1074         my $proto = $c->tx->with_protocols('v2.proto', 'v1.proto');
1075
1076       You can also use "with_protocols" in Mojo::Transaction::WebSocket to
1077       negotiate a subprotocol.
1078
1079   EventSource web service
1080       EventSource is a special form of long polling where you can use "write"
1081       in Mojolicious::Controller to directly send DOM events from servers to
1082       clients. It is uni-directional, that means you will have to use Ajax
1083       requests for sending data from clients to servers, the advantage
1084       however is low infrastructure requirements, since it reuses the HTTP
1085       protocol for transport.
1086
1087         use Mojolicious::Lite -signatures;
1088
1089         # Template with browser-side code
1090         get '/' => 'index';
1091
1092         # EventSource for log messages
1093         get '/events' => sub ($c) {
1094
1095           # Increase inactivity timeout for connection a bit
1096           $c->inactivity_timeout(300);
1097
1098           # Change content type and finalize response headers
1099           $c->res->headers->content_type('text/event-stream');
1100           $c->write;
1101
1102           # Subscribe to "message" event and forward "log" events to browser
1103           my $cb = $c->app->log->on(message => sub ($log, $level, @lines) {
1104             $c->write("event:log\ndata: [$level] @lines\n\n");
1105           });
1106
1107           # Unsubscribe from "message" event again once we are done
1108           $c->on(finish => sub ($c) {
1109             $c->app->log->unsubscribe(message => $cb);
1110           });
1111         };
1112
1113         app->start;
1114         __DATA__
1115
1116         @@ index.html.ep
1117         <!DOCTYPE html>
1118         <html>
1119           <head><title>LiveLog</title></head>
1120           <body>
1121             <script>
1122               const events = new EventSource('<%= url_for 'events' %>');
1123
1124               // Subscribe to "log" event
1125               events.addEventListener('log', function (event) {
1126                 document.body.innerHTML += event.data + '<br/>';
1127               }, false);
1128             </script>
1129           </body>
1130         </html>
1131
1132       The event "message" in Mojo::Log will be emitted for every new log
1133       message and the event "finish" in Mojo::Transaction right after the
1134       transaction has been finished.
1135
1136   Streaming multipart uploads
1137       Mojolicious contains a very sophisticated event system based on
1138       Mojo::EventEmitter, with ready-to-use events on almost all layers, and
1139       which can be combined to solve some of the hardest problems in web
1140       development.
1141
1142         use Mojolicious::Lite -signatures;
1143         use Scalar::Util qw(weaken);
1144
1145         # Intercept multipart uploads and log each chunk received
1146         hook after_build_tx => sub ($tx, $app) {
1147
1148           # Subscribe to "upgrade" event to identify multipart uploads
1149           weaken $tx;
1150           $tx->req->content->on(upgrade => sub ($single, $multi) {
1151             return unless $tx->req->url->path->contains('/upload');
1152
1153             # Subscribe to "part" event to find the right one
1154             $multi->on(part => sub ($multi, $single) {
1155
1156               # Subscribe to "body" event of part to make sure we have all headers
1157               $single->on(body => sub ($single) {
1158
1159                 # Make sure we have the right part and replace "read" event
1160                 return unless $single->headers->content_disposition =~ /example/;
1161                 $single->unsubscribe('read')->on(read => sub ($single, $bytes) {
1162
1163                   # Log size of every chunk we receive
1164                   $app->log->debug(length($bytes) . ' bytes uploaded');
1165                 });
1166               });
1167             });
1168           });
1169         };
1170
1171         # Upload form in DATA section
1172         get '/' => 'index';
1173
1174         # Streaming multipart upload
1175         post '/upload' => {text => 'Upload was successful.'};
1176
1177         app->start;
1178         __DATA__
1179
1180         @@ index.html.ep
1181         <!DOCTYPE html>
1182         <html>
1183           <head><title>Streaming multipart upload</title></head>
1184           <body>
1185             %= form_for upload => (enctype => 'multipart/form-data') => begin
1186               %= file_field 'example'
1187               %= submit_button 'Upload'
1188             % end
1189           </body>
1190         </html>
1191
1192   More event loops
1193       Internally, the Mojo::IOLoop event loop can use multiple reactor
1194       backends, EV for example, will be automatically used if possible. Which
1195       in turn allows other event loops like AnyEvent to just work.
1196
1197         use Mojolicious::Lite -signatures;
1198         use EV;
1199         use AnyEvent;
1200
1201         # Wait 3 seconds before rendering a response
1202         get '/' => sub ($c) {
1203           my $w;
1204           $w = AE::timer 3, 0, sub {
1205             $c->render(text => 'Delayed by 3 seconds!');
1206             undef $w;
1207           };
1208         };
1209
1210         app->start;
1211

USER AGENT

1213       When we say Mojolicious is a web framework we actually mean it, with
1214       Mojo::UserAgent there's a full featured HTTP and WebSocket user agent
1215       built right in.
1216
1217   REST web services
1218       Requests can be performed very comfortably with methods like "get" in
1219       Mojo::UserAgent, and always result in a Mojo::Transaction::HTTP object,
1220       which has many useful attributes and methods. You can check for
1221       connection errors with "result" in Mojo::Transaction, or access HTTP
1222       request and response information directly through "req" in
1223       Mojo::Transaction and "res" in Mojo::Transaction.
1224
1225         use Mojo::UserAgent;
1226
1227         # Request a resource and make sure there were no connection errors
1228         my $ua = Mojo::UserAgent->new;
1229         my $tx = $ua->get('https://docs.mojolicious.org/Mojo' => {Accept => 'text/plain'});
1230         my $res = $tx->result;
1231
1232         # Decide what to do with its representation
1233         if    ($res->is_success)  { say $res->body }
1234         elsif ($res->is_error)    { say $res->message }
1235         elsif ($res->code == 301) { say $res->headers->location }
1236         else                      { say 'Whatever...' }
1237
1238       While methods like "is_success" in Mojo::Message::Response and
1239       "is_error" in Mojo::Message::Response serve as building blocks for more
1240       sophisticated REST clients.
1241
1242   Web scraping
1243       Scraping information from websites has never been this much fun before.
1244       The built-in HTML/XML parser Mojo::DOM is accessible through "dom" in
1245       Mojo::Message and supports all CSS selectors that make sense for a
1246       standalone parser, it can be a very powerful tool especially for
1247       testing web application.
1248
1249         use Mojo::UserAgent;
1250
1251         # Fetch website
1252         my $ua = Mojo::UserAgent->new;
1253         my $res = $ua->get('https://docs.mojolicious.org')->result;
1254
1255         # Extract title
1256         say 'Title: ', $res->dom->at('head > title')->text;
1257
1258         # Extract headings
1259         $res->dom('h1, h2, h3')->each(sub ($dom, $i) {
1260           say 'Heading: ', $dom->all_text;
1261         });
1262
1263         # Visit all nodes recursively to extract more than just text
1264         for my $n ($res->dom->descendant_nodes->each) {
1265
1266           # Text or CDATA node
1267           print $n->content if $n->type eq 'text' || $n->type eq 'cdata';
1268
1269           # Also include alternate text for images
1270           print $n->{alt} if $n->type eq 'tag' && $n->tag eq 'img';
1271         }
1272
1273       For a full list of available CSS selectors see "SELECTORS" in
1274       Mojo::DOM::CSS.
1275
1276   JSON web services
1277       Most web services these days are based on the JSON data-interchange
1278       format. That's why Mojolicious comes with the possibly fastest pure-
1279       Perl implementation Mojo::JSON built right in, which is accessible
1280       through "json" in Mojo::Message.
1281
1282         use Mojo::UserAgent;
1283         use Mojo::URL;
1284
1285         # Fresh user agent
1286         my $ua = Mojo::UserAgent->new;
1287
1288         # Search MetaCPAN for "mojolicious" and list latest releases
1289         my $url = Mojo::URL->new('http://fastapi.metacpan.org/v1/release/_search');
1290         $url->query({q => 'mojolicious', sort => 'date:desc'});
1291         for my $hit (@{$ua->get($url)->result->json->{hits}{hits}}) {
1292           say "$hit->{_source}{name} ($hit->{_source}{author})";
1293         }
1294
1295   Basic authentication
1296       You can just add username and password to the URL, an "Authorization"
1297       header will be automatically generated.
1298
1299         use Mojo::UserAgent;
1300
1301         my $ua = Mojo::UserAgent->new;
1302         say $ua->get('https://sri:secret@example.com/hideout')->result->body;
1303
1304       If you're using Mojo::URL to build the URL, be aware that the userinfo
1305       part will not be included if the object is stringified. You'll have to
1306       pass the object itself to Mojo::UserAgent or use "to_unsafe_string" in
1307       Mojo::URL.
1308
1309         use Mojo::UserAgent;
1310         use Mojo::URL;
1311
1312         my $ua  = Mojo::UserAgent->new;
1313         my $url = Mojo::URL->new('https://example.com/hideout')->userinfo('sri:secret');
1314         say $ua->get($url)->result->body;
1315
1316   Decorating follow-up requests
1317       Mojo::UserAgent can automatically follow redirects, the event "start"
1318       in Mojo::UserAgent allows you direct access to each transaction right
1319       after they have been initialized and before a connection gets
1320       associated with them.
1321
1322         use Mojo::UserAgent;
1323
1324         # User agent following up to 10 redirects
1325         my $ua = Mojo::UserAgent->new(max_redirects => 10);
1326
1327         # Add a witty header to every request
1328         $ua->on(start => sub ($ua, $tx) {
1329           $tx->req->headers->header('X-Bender' => 'Bite my shiny metal ass!');
1330           say 'Request: ', $tx->req->url->clone->to_abs;
1331         });
1332
1333         # Request that will most likely get redirected
1334         say 'Title: ', $ua->get('google.com')->result->dom->at('head > title')->text;
1335
1336       This even works for proxy "CONNECT" requests.
1337
1338   Content generators
1339       Content generators can be registered with "add_generator" in
1340       Mojo::UserAgent::Transactor to generate the same type of content
1341       repeatedly for multiple requests.
1342
1343         use Mojo::UserAgent;
1344         use Mojo::Asset::File;
1345
1346         # Add "stream" generator
1347         my $ua = Mojo::UserAgent->new;
1348         $ua->transactor->add_generator(stream => sub ($transactor, $tx, $path) {
1349           $tx->req->content->asset(Mojo::Asset::File->new(path => $path));
1350         });
1351
1352         # Send multiple files streaming via PUT and POST
1353         $ua->put('http://example.com/upload'  => stream => '/home/sri/mojo.png');
1354         $ua->post('http://example.com/upload' => stream => '/home/sri/minion.png');
1355
1356       The "json", "form" and "multipart" content generators are always
1357       available.
1358
1359         use Mojo::UserAgent;
1360
1361         # Send "application/json" content via PATCH
1362         my $ua = Mojo::UserAgent->new;
1363         my $tx = $ua->patch('http://api.example.com' => json => {foo => 'bar'});
1364
1365         # Send query parameters via GET
1366         my $tx2 = $ua->get('search.example.com' => form => {q => 'test'});
1367
1368         # Send "application/x-www-form-urlencoded" content via POST
1369         my $tx3 = $ua->post('http://search.example.com' => form => {q => 'test'});
1370
1371         # Send "multipart/form-data" content via PUT
1372         my $tx4 = $ua->put('upload.example.com' => form => {test => {content => 'Hello World!'}});
1373
1374         # Send custom multipart content via PUT
1375         my $tx5 = $ua->put('api.example.com' => multipart => ['Hello', 'World!']);
1376
1377       For more information about available content generators see also "tx"
1378       in Mojo::UserAgent::Transactor.
1379
1380   Large file downloads
1381       When downloading large files with Mojo::UserAgent you don't have to
1382       worry about memory usage at all, because it will automatically stream
1383       everything above 250KiB into a temporary file, which can then be moved
1384       into a permanent file with "save_to" in Mojo::Message.
1385
1386         use Mojo::UserAgent;
1387
1388         # Fetch the latest Mojolicious tarball
1389         my $ua = Mojo::UserAgent->new(max_redirects => 5);
1390         my $tx = $ua->get('https://www.github.com/mojolicious/mojo/tarball/main');
1391         $tx->result->save_to('mojo.tar.gz');
1392
1393       To protect you from excessively large files there is also a limit of
1394       2GiB by default, which you can tweak with the attribute
1395       "max_response_size" in Mojo::UserAgent.
1396
1397         # Increase limit to 10GiB
1398         $ua->max_response_size(10737418240);
1399
1400   Large file upload
1401       Uploading a large file is even easier.
1402
1403         use Mojo::UserAgent;
1404
1405         # Upload file via POST and "multipart/form-data"
1406         my $ua = Mojo::UserAgent->new;
1407         $ua->post('example.com/upload' => form => {image => {file => '/home/sri/hello.png'}});
1408
1409       And once again you don't have to worry about memory usage, all data
1410       will be streamed directly from the file.
1411
1412   Streaming response
1413       Receiving a streaming response can be really tricky in most HTTP
1414       clients, but Mojo::UserAgent makes it actually easy.
1415
1416         use Mojo::UserAgent;
1417
1418         # Accept responses of indefinite size
1419         my $ua = Mojo::UserAgent->new(max_response_size => 0);
1420
1421         # Build a normal transaction
1422         my $tx = $ua->build_tx(GET => 'http://example.com');
1423
1424         # Replace "read" events to disable default content parser
1425         $tx->res->content->unsubscribe('read')->on(read => sub ($content, $bytes) {
1426           say "Streaming: $bytes";
1427         });
1428
1429         # Process transaction
1430         $tx = $ua->start($tx);
1431
1432       The event "read" in Mojo::Content will be emitted for every chunk of
1433       data that is received, even chunked transfer encoding and gzip content
1434       encoding will be handled transparently if necessary.
1435
1436   Streaming request
1437       Sending a streaming request is almost just as easy.
1438
1439         use Mojo::UserAgent;
1440
1441         # Build a normal transaction
1442         my $ua = Mojo::UserAgent->new;
1443         my $tx = $ua->build_tx(GET => 'http://example.com');
1444
1445         # Prepare body
1446         my $body = 'Hello World!';
1447         $tx->req->headers->content_length(length $body);
1448
1449         # Start writing directly with a drain callback
1450         my $drain = sub ($content) {
1451           my $chunk = substr $body, 0, 1, '';
1452           $content->write($chunk, length $body ? __SUB__ : undef);
1453         };
1454         $tx->req->content->$drain;
1455
1456         # Process transaction
1457         $tx = $ua->start($tx);
1458
1459       The drain callback passed to "write" in Mojo::Content will be executed
1460       whenever the entire previous chunk of data has actually been written.
1461
1462   Non-blocking
1463       Mojo::UserAgent has been designed from the ground up to be non-
1464       blocking, the whole blocking API is just a simple convenience wrapper.
1465       Especially for high latency tasks like web crawling this can be
1466       extremely useful, because you can keep many concurrent connections
1467       active at the same time.
1468
1469         use Mojo::UserAgent;
1470         use Mojo::IOLoop;
1471
1472         # Concurrent non-blocking requests
1473         my $ua = Mojo::UserAgent->new;
1474         $ua->get('https://metacpan.org/search?q=mojo' => sub ($ua, $mojo) {
1475           say $mojo->result->dom->at('title')->text;
1476         });
1477         $ua->get('https://metacpan.org/search?q=minion' => sub ($ua, $minion) {
1478           say $minion->result->dom->at('title')->text;
1479         });
1480
1481         # Start event loop if necessary
1482         Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
1483
1484       But don't try to open too many connections to one server at the same
1485       time, it might get overwhelmed. Better use a queue to process requests
1486       in smaller batches.
1487
1488         use Mojo::Promise;
1489         use Mojo::UserAgent;
1490
1491         my @urls = (
1492           'https://docs.mojolicious.org/Mojo/DOM',  'https://docs.mojolicious.org/Mojo',
1493           'https://docs.mojolicious.org/Mojo/File', 'https://docs.mojolicious.org/Mojo/URL'
1494         );
1495
1496         # User agent with a custom name, following up to 5 redirects
1497         my $ua = Mojo::UserAgent->new(max_redirects => 5);
1498         $ua->transactor->name('MyParallelCrawler 1.0');
1499
1500         # Use a promise to keep the event loop running until we are done
1501         my $promise = Mojo::Promise->new;
1502         my $count = 0;
1503         my $fetch = sub {
1504
1505           # Stop if there are no more URLs
1506           return unless my $url = shift @urls;
1507
1508           # Fetch the next title
1509           $ua->get($url => sub ($ua, $tx) {
1510             say "$url: ", $tx->result->dom->at('title')->text;
1511
1512             # Next request
1513             __SUB__->();
1514             $promise->resolve if --$count == 0;
1515           });
1516           $count++;
1517         };
1518
1519         # Process two requests at a time
1520         $fetch->() for 1 .. 2;
1521         $promise->wait;
1522
1523       It is also strongly recommended to respect every sites "robots.txt"
1524       file as well as terms of service, and to wait a little before reopening
1525       connections to the same host, or the operators might be forced to block
1526       your access.
1527
1528   Concurrent blocking requests
1529       You might have seen "wait" in Mojo::Promise already in some examples
1530       above. It is used to make non-blocking operations portable, allowing
1531       them to work inside an already running event loop or start one on
1532       demand.
1533
1534         use Mojo::UserAgent;
1535         use Mojo::Promise;
1536
1537         # Synchronize non-blocking requests with promises
1538         my $ua = Mojo::UserAgent->new;
1539         my $mojo_promise   = $ua->get_p('https://metacpan.org/search?q=mojo');
1540         my $minion_promise = $ua->get_p('https://metacpan.org/search?q=minion');
1541         Mojo::Promise->all($mojo_promise, $minion_promise)->then(sub ($mojo, $minion) {
1542           say $mojo->[0]->result->dom->at('title')->text;
1543           say $minion->[0]->result->dom->at('title')->text;
1544         })->wait;
1545
1546   WebSockets
1547       WebSockets are not just for the server-side, you can use "websocket_p"
1548       in Mojo::UserAgent to open new connections, which are always non-
1549       blocking. The WebSocket handshake uses HTTP, and is a normal "GET"
1550       request with a few additional headers. It can even contain cookies, and
1551       is followed by a 101 response from the server, notifying our user agent
1552       that the connection has been established and it can start using the bi-
1553       directional WebSocket protocol.
1554
1555         use Mojo::UserAgent;
1556         use Mojo::Promise;
1557
1558         # Open WebSocket to echo service
1559         my $ua = Mojo::UserAgent->new;
1560         $ua->websocket_p('ws://echo.websocket.org')->then(sub ($tx) {
1561
1562           # Prepare a followup promise so we can wait for messages
1563           my $promise = Mojo::Promise->new;
1564
1565           # Wait for WebSocket to be closed
1566           $tx->on(finish => sub ($tx, $code, $reason) {
1567             say "WebSocket closed with status $code.";
1568             $promise->resolve;
1569           });
1570
1571           # Close WebSocket after receiving one message
1572           $tx->on(message => sub ($tx, $msg) {
1573             say "WebSocket message: $msg";
1574             $tx->finish;
1575           });
1576
1577           # Send a message to the server
1578           $tx->send('Hi!');
1579
1580           # Insert a new promise into the promise chain
1581           return $promise;
1582         })->catch(sub ($err) {
1583
1584           # Handle failed WebSocket handshakes and other exceptions
1585           warn "WebSocket error: $err";
1586         })->wait;
1587
1588   UNIX domain sockets
1589       Not just TCP/IP sockets are supported, but also UNIX domain sockets,
1590       which can have significant security and performance benefits when used
1591       for inter-process communication. Instead of "http://" and "ws://" you
1592       can use the "http+unix://" and "ws+unix://" schemes, and pass along a
1593       percent encoded path ("/" becomes %2F) instead of a hostname.
1594
1595         use Mojo::UserAgent;
1596         use Mojo::Promise;
1597
1598         # GET request via UNIX domain socket "/tmp/foo.sock"
1599         my $ua = Mojo::UserAgent->new;
1600         say $ua->get('http+unix://%2Ftmp%2Ffoo.sock/index.html')->result->body;
1601
1602         # GET request with HOST header via UNIX domain socket "/tmp/bar.sock"
1603         my $tx = $ua->get('http+unix://%2Ftmp%2Fbar.sock' => {Host => 'example.com'});
1604         say $tx->result->body;
1605
1606         # WebSocket connection via UNIX domain socket "/tmp/baz.sock"
1607         $ua->websocket_p('ws+unix://%2Ftmp%2Fbaz.sock/echo')->then(sub ($tx) {
1608
1609           my $promise = Mojo::Promise->new;
1610           $tx->on(finish => sub ($tx) { $promise->resolve });
1611
1612           $tx->on(message => sub ($tx, $msg) {
1613             say "WebSocket message: $msg";
1614             $tx->finish;
1615           });
1616           $tx->send('Hi!');
1617
1618           return $promise;
1619         })->catch(sub ($err) {
1620           warn "WebSocket error: $err";
1621         })->wait;
1622
1623       You can set the "Host" header manually to pass along a hostname.
1624
1625   Command line
1626       Don't you hate checking huge HTML files from the command line? Thanks
1627       to the command Mojolicious::Command::get that is about to change. You
1628       can just pick the parts that actually matter with the CSS selectors
1629       from Mojo::DOM and JSON Pointers from Mojo::JSON::Pointer.
1630
1631         $ mojo get https://mojolicious.org 'head > title'
1632
1633       How about a list of all id attributes?
1634
1635         $ mojo get https://mojolicious.org '*' attr id
1636
1637       Or the text content of all heading tags?
1638
1639         $ mojo get https://mojolicious.org 'h1, h2, h3' text
1640
1641       Maybe just the text of the third heading?
1642
1643         $ mojo get https://mojolicious.org 'h1, h2, h3' 3 text
1644
1645       You can also extract all text from nested child elements.
1646
1647         $ mojo get https://mojolicious.org '#mojobar' all
1648
1649       The request can be customized as well.
1650
1651         $ mojo get -M POST -H 'X-Bender: Bite my shiny metal ass!' http://google.com
1652
1653       Store response data by redirecting "STDOUT".
1654
1655         $ mojo get mojolicious.org > example.html
1656
1657       Pass request data by redirecting "STDIN".
1658
1659         $ mojo get -M PUT mojolicious.org < example.html
1660
1661       Or use the output of another program.
1662
1663         $ echo 'Hello World' | mojo get -M PUT https://mojolicious.org
1664
1665       Submit forms as "application/x-www-form-urlencoded" content.
1666
1667         $ mojo get -M POST -f 'q=Mojo' -f 'size=5' https://metacpan.org/search
1668
1669       And upload files as "multipart/form-data" content.
1670
1671         $ mojo get -M POST -f 'upload=@example.html' mojolicious.org
1672
1673       You can follow redirects and view the headers for all messages.
1674
1675         $ mojo get -r -v http://google.com 'head > title'
1676
1677       Extract just the information you really need from JSON data structures.
1678
1679         $ mojo get https://fastapi.metacpan.org/v1/author/SRI /name
1680
1681       This can be an invaluable tool for testing your applications.
1682
1683         $ ./myapp.pl get /welcome 'head > title'
1684
1685   One-liners
1686       For quick hacks and especially testing, ojo one-liners are also a great
1687       choice.
1688
1689         $ perl -Mojo -E 'say g("mojolicious.org")->dom->at("title")->text'
1690

APPLICATIONS

1692       Fun Mojolicious application hacks for all occasions.
1693
1694   Basic authentication
1695       Basic authentication data will be automatically extracted from the
1696       "Authorization" header.
1697
1698         use Mojolicious::Lite -signatures;
1699         use Mojo::Util qw(secure_compare);
1700
1701         get '/' => sub ($c) {
1702
1703           # Check for username "Bender" and password "rocks"
1704           return $c->render(text => 'Hello Bender!') if secure_compare $c->req->url->to_abs->userinfo, 'Bender:rocks';
1705
1706           # Require authentication
1707           $c->res->headers->www_authenticate('Basic');
1708           $c->render(text => 'Authentication required!', status => 401);
1709         };
1710
1711         app->start;
1712
1713       This can be combined with TLS for a secure authentication mechanism.
1714
1715         $ ./myapp.pl daemon -l 'https://*:3000?cert=./server.crt&key=./server.key'
1716
1717   Adding a configuration file
1718       Adding a configuration file to your application is as easy as adding a
1719       file to its home directory and loading the plugin
1720       Mojolicious::Plugin::Config. The default name is based on the value of
1721       "moniker" in Mojolicious ("myapp"), appended with a ".conf" extension
1722       ("myapp.conf").
1723
1724         $ mkdir myapp
1725         $ cd myapp
1726         $ touch myapp.pl
1727         $ chmod 744 myapp.pl
1728         $ echo '{name => "my Mojolicious application"};' > myapp.conf
1729
1730       Configuration files themselves are just Perl scripts that return a hash
1731       reference with configuration settings of your choice. All those
1732       settings are then available through the method "config" in Mojolicious
1733       and the helper "config" in Mojolicious::Plugin::DefaultHelpers.
1734
1735         use Mojolicious::Lite;
1736
1737         plugin 'Config';
1738
1739         my $name = app->config('name');
1740         app->log->debug("Welcome to $name");
1741
1742         get '/' => 'with_config';
1743
1744         app->start;
1745         __DATA__
1746         @@ with_config.html.ep
1747         <!DOCTYPE html>
1748         <html>
1749           <head><title><%= config 'name' %></title></head>
1750           <body>Welcome to <%= config 'name' %></body>
1751         </html>
1752
1753       Alternatively you can also use configuration files in the JSON format
1754       with Mojolicious::Plugin::JSONConfig.
1755
1756   Adding a plugin to your application
1757       To organize your code better and to prevent helpers from cluttering
1758       your application, you can use application specific plugins.
1759
1760         $ mkdir -p lib/MyApp/Plugin
1761         $ touch lib/MyApp/Plugin/MyHelpers.pm
1762
1763       They work just like normal plugins and are also subclasses of
1764       Mojolicious::Plugin. Nested helpers with a prefix based on the plugin
1765       name are an easy way to avoid conflicts.
1766
1767         package MyApp::Plugin::MyHelpers;
1768         use Mojo::Base 'Mojolicious::Plugin', -signatures;
1769
1770         sub register ($self, $app, $conf) {
1771           $app->helper('my_helpers.render_with_header' => sub ($c, @args) {
1772             $c->res->headers->header('X-Mojo' => 'I <3 Mojolicious!');
1773             $c->render(@args);
1774           });
1775         }
1776
1777         1;
1778
1779       You can have as many application specific plugins as you like, the only
1780       difference to normal plugins is that you load them using their full
1781       class name.
1782
1783         use Mojolicious::Lite -signatures;
1784
1785         use lib qw(lib);
1786
1787         plugin 'MyApp::Plugin::MyHelpers';
1788
1789         get '/' => sub ($c) {
1790           $c->my_helpers->render_with_header(text => 'I ♥ Mojolicious!');
1791         };
1792
1793         app->start;
1794
1795       Of course these plugins can contain more than just helpers, take a look
1796       at "PLUGINS" in Mojolicious::Plugins for a few ideas.
1797
1798   Adding commands to Mojolicious
1799       By now you've probably used many of the built-in commands described in
1800       Mojolicious::Commands, but did you know that you can just add new ones
1801       and that they will be picked up automatically by the command line
1802       interface if they are placed in a directory from @INC?
1803
1804         package Mojolicious::Command::spy;
1805         use Mojo::Base 'Mojolicious::Command', -signatures;
1806
1807         has description => 'Spy on application';
1808         has usage       => "Usage: APPLICATION spy [TARGET]\n";
1809
1810         sub run ($self, @args) {
1811
1812           # Leak secret passphrases
1813           if ($args[0] eq 'secrets') { say for @{$self->app->secrets} }
1814
1815           # Leak mode
1816           elsif ($args[0] eq 'mode') { say $self->app->mode }
1817         }
1818
1819         1;
1820
1821       Command line arguments are passed right through and there are many
1822       useful attributes and methods in Mojolicious::Command that you can use
1823       or overload.
1824
1825         $ mojo spy secrets
1826         HelloWorld
1827
1828         $ ./script/myapp spy secrets
1829         secr3t
1830
1831       And to make your commands application specific, just add a custom
1832       namespace to "namespaces" in Mojolicious::Commands and use a class name
1833       like "MyApp::Command::spy" instead of "Mojolicious::Command::spy".
1834
1835         # Application
1836         package MyApp;
1837         use Mojo::Base 'Mojolicious', -signatures;
1838
1839         sub startup ($self) {
1840
1841           # Add another namespace to load commands from
1842           push @{$self->commands->namespaces}, 'MyApp::Command';
1843         }
1844
1845         1;
1846
1847       The options "-h"/"--help", "--home" and "-m"/"--mode" are handled
1848       automatically by Mojolicious::Commands and are shared by all commands.
1849
1850         $ ./script/myapp spy -m production mode
1851         production
1852
1853       For a full list of shared options see "SYNOPSIS" in
1854       Mojolicious::Commands.
1855
1856   Running code against your application
1857       Ever thought about running a quick one-liner against your Mojolicious
1858       application to test something? Thanks to the command
1859       Mojolicious::Command::eval you can do just that, the application object
1860       itself can be accessed via "app".
1861
1862         $ mojo generate lite-app myapp.pl
1863         $ ./myapp.pl eval 'say for @{app->static->paths}'
1864         $ ./myapp.pl eval 'say for sort keys %{app->renderer->helpers}'
1865
1866       The "verbose" options will automatically print the return value or
1867       returned data structure to "STDOUT".
1868
1869         $ ./myapp.pl eval -v 'app->static->paths->[0]'
1870         $ ./myapp.pl eval -V 'app->static->paths'
1871
1872   Making your application installable
1873       Ever thought about releasing your Mojolicious application to CPAN? It's
1874       actually much easier than you might think.
1875
1876         $ mojo generate app MyApp
1877         $ cd my_app
1878         $ mv public lib/MyApp/
1879         $ mv templates lib/MyApp/
1880
1881       The trick is to move the "public" and "templates" directories so they
1882       can get automatically installed with the modules. Additionally author
1883       commands from the "Mojolicious::Command::Author" namespace are not
1884       usually wanted by an installed application so they can be excluded.
1885
1886         # Application
1887         package MyApp;
1888         use Mojo::Base 'Mojolicious', -signatures;
1889
1890         use Mojo::File qw(curfile);
1891         use Mojo::Home;
1892
1893         # Every CPAN module needs a version
1894         our $VERSION = '1.0';
1895
1896         sub startup ($self) {
1897
1898           # Switch to installable home directory
1899           $self->home(Mojo::Home->new(curfile->sibling('MyApp')));
1900
1901           # Switch to installable "public" directory
1902           $self->static->paths->[0] = $self->home->child('public');
1903
1904           # Switch to installable "templates" directory
1905           $self->renderer->paths->[0] = $self->home->child('templates');
1906
1907           # Exclude author commands
1908           $self->commands->namespaces(['Mojolicious::Commands']);
1909
1910           my $r = $self->routes;
1911           $r->get('/welcome')->to('example#welcome');
1912         }
1913
1914         1;
1915
1916       Finally there is just one small change to be made to the application
1917       script. The shebang line becomes the recommended "#!perl", which the
1918       toolchain can rewrite to the proper shebang during installation.
1919
1920         #!perl
1921
1922         use strict;
1923         use warnings;
1924
1925         use Mojo::File qw(curfile);
1926         use lib curfile->dirname->sibling('lib')->to_string;
1927         use Mojolicious::Commands;
1928
1929         # Start command line interface for application
1930         Mojolicious::Commands->start_app('MyApp');
1931
1932       That's really everything, now you can package your application like any
1933       other CPAN module.
1934
1935         $ ./script/my_app generate makefile
1936         $ perl Makefile.PL
1937         $ make test
1938         $ make manifest
1939         $ make dist
1940
1941       And if you have a PAUSE account (which can be requested at
1942       <http://pause.perl.org>) even upload it.
1943
1944         $ mojo cpanify -u USER -p PASS MyApp-0.01.tar.gz
1945
1946   Proxy
1947       While every Mojolicious application has the built-in user agent "ua" in
1948       Mojolicious::Plugin::DefaultHelpers for you to perform requests to
1949       backend web services, this is not always the most efficient solution.
1950       The specialized proxy helpers "proxy->get_p" in
1951       Mojolicious::Plugin::DefaultHelpers and "proxy->start_p" in
1952       Mojolicious::Plugin::DefaultHelpers can stream response content
1953       straight to the client, as soon as a new chunk of data is received from
1954       the backend web service. Additionally they will take care of removing
1955       hop-by-hop headers and protect you automatically from backpressure
1956       issues. Which can happen in situations where the connection to the
1957       backend web service is faster than the connection to the client and
1958       data forwarding needs to be throttled. And the best of all, everything
1959       happens non-blocking, that means your web server can process other
1960       requestes concurrently while waiting for I/O.
1961
1962         use Mojolicious::Lite -signatures;
1963
1964         # Just forward the response
1965         get '/' => sub ($c) {
1966           $c->proxy->get_p('https://mojolicious.org')->catch(sub ($err) {
1967             $c->log->error("Proxy error: $err");
1968             $c->render(text => 'Could not connect to backend web service!', status => 400);
1969           });
1970         };
1971
1972         # Forward response and customize a few things
1973         get '/*docs' => sub ($c) {
1974
1975           # Custom request
1976           my $tx = $c->ua->build_tx(GET => 'https://docs.mojolicious.org');
1977           my $docs = $c->param('docs');
1978           $tx->req->url->path("/$docs");
1979           $tx->req->headers->user_agent('MojoProxy/1.0');
1980
1981           # Start non-blocking request
1982           $c->proxy->start_p($tx)->catch(sub ($err) {
1983             $c->log->error("Proxy error: $err");
1984             $c->render(text => 'Could not connect to backend web service!', status => 400);
1985           });
1986
1987           # Custom response
1988           $tx->res->content->once(body => sub ($content) {
1989             $c->res->headers->server('MojoProxy/1.0');
1990           });
1991         };
1992
1993         app->start;
1994
1995       All proxy helpers return a Mojo::Promise object, which should be used
1996       to handle connection errors to backend web services gracefully. And if
1997       you ever need to forward all headers from the client to the backend web
1998       service, make sure to use "dehop" in Mojo::Headers to remove all hop-
1999       by-hop headers.
2000
2001         # Clone and modify request headers
2002         my $headers = $c->req->headers->clone->dehop;
2003         $headers->accept('application/json');
2004         my $tx = $c->ua->build_tx(PUT => 'https://mojolicious.org' => $headers->to_hash);
2005
2006   Hello World
2007       If every byte matters this is the smallest "Hello World" application
2008       you can write with Mojolicious::Lite.
2009
2010         use Mojolicious::Lite;
2011         any {text => 'Hello World!'};
2012         app->start;
2013
2014       It works because all routes without a pattern default to "/" and
2015       automatic rendering kicks in even if no actual code gets executed by
2016       the router. The renderer just picks up the "text" value from the stash
2017       and generates a response.
2018
2019   Hello World one-liners
2020       The "Hello World" example above can get even a little bit shorter in an
2021       ojo one-liner.
2022
2023         $ perl -Mojo -E 'a({text => "Hello World!"})->start' daemon
2024
2025       And you can use all the commands from Mojolicious::Commands.
2026
2027         $ perl -Mojo -E 'a({text => "Hello World!"})->start' get -v /
2028

MORE

2030       You can continue with Mojolicious::Guides now or take a look at the
2031       Mojolicious wiki <https://github.com/mojolicious/mojo/wiki>, which
2032       contains a lot more documentation and examples by many different
2033       authors.
2034

SUPPORT

2036       If you have any questions the documentation might not yet answer, don't
2037       hesitate to ask in the Forum <https://forum.mojolicious.org>, on Matrix
2038       <https://matrix.to/#/#mojo:matrix.org>, or IRC
2039       <https://web.libera.chat/#mojo>.
2040
2041
2042
2043perl v5.36.0                      2022-07-22  Mojolicious::Guides::Cookbook(3)
Impressum