TABLE OF CONTENTS

文档

Mojolicious::Lite - Real-time micro web framework

概述

# 自动打开 "strict", "warnings" 和 Perl 5.10 特性
use Mojolicious::Lite;

# 占位符的路径选择
get '/:foo' => sub {
  my $c = shift;
  my $foo  = $c->param('foo');
  $c->render(text => "Hello from $foo.");
};

# 启用 Mojolicious 命令行体系
app->start;

描述

Mojolicious::Lite 是由 Mojolicious 做的一个实时 web 框架.

更新到版本 5.05.

教程

一个简单的例子来给你介绍, 在 Mojolicious::Lite 中的奇妙之处. 你会在这里学到的大多数也适用于全功能的 Mojolicious 应用.

Hello World

下面是一个简单的 Hello World 的应用程序.因为在 Perl 5.10 中会默认启用 strict, warnings 几个功能.并导入 Mojolicious::Lite 的功能, 让你的脚本本成一个全功能的 web 应用.

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $c = shift;
  $c->render(text => 'Hello World!');
};

app->start;

这有一个辅助命令来生成这个例子中的应用程序

$ mojo generate lite_app myapp.pl

Commands

这些标准的 Mojolicious::Commands 中会提供一些常用的命令行功能. 注意它可以自动的对 CGI 和 PSGI 的环境检查出来.可 以不提供参数.

$ ./myapp.pl daemon
Server available at http://127.0.0.1:3000.

$ ./myapp.pl daemon -l http://*:8080
Server available at http://127.0.0.1:8080.

$ ./myapp.pl cgi
...CGI output...

$ ./myapp.pl get /
Hello World!

$ ./myapp.pl
...List of available commands (or automatically detected environment)...

你可以在 app->start 的调用中加入参数, 来替换掉标准的从 @ARGV 中接收参数.

app->start('cgi');

修改代码后自动加载

如果你想你的应用在修改后能自动的 reload 加载你的修改的程序, 建议你使用 morbo 的开发用的 web 服务器, 这样你就不用每次修改后重起.

$ morbo myapp.pl
Server available at http://127.0.0.1:3000.

译者注: 默认只监控 "lib" 和 "templates" 的文件夹内的改变, 如果你想加入指定的路径的文件进行监控修改后自动重起, 可以使用 -w 参数

$ morbo -w /myhome/lib myapp.pl

关如何部署你的应用程序的更多信息, 请看 "DEPLOYMENT" in Mojolicious::Guides::Cookbook.

Routes

Routes 只是对请求过来的路径指向不同的函数. 可以在路径中包含不同的占位符. 传进来的第一个参数是 $cMojolicious::Controller 对象本身, 它也包含着 HTTP request 和 HTTP response 的对象.

use Mojolicious::Lite;

# /foo
get '/foo' => sub {
  my $c = shift;
  $c->render(text => 'Hello World!');
};

app->start;

响应的内容通常是由 "render" in Mojolicious::Controller 的动作产生的, 后面会讲到.

GET/POST 传进来的参数

全部的 GETPOST 的参数只需要通过 "param" in Mojolicious::Controller 来访问.

use Mojolicious::Lite;

# /foo?user=sri
get '/foo' => sub {
  my $c = shift;
  my $user = $c->param('user');
  $c->render(text => "Hello $user.");
};

app->start;

Stash 和模板 ( templates )

这个 "stash" in Mojolicious::Controller 是用来传一些数据给模板技术使用, 在这我们使用的模板是存储在 DATA 这个部分中的 @@ 标记的位置内容.

use Mojolicious::Lite;

# /bar
get '/bar' => sub {
  my $c = shift;
  $c->stash(one => 23);
  $c->render('baz', two => 24);
};

app->start;
__DATA__

@@ baz.html.ep
The magic numbers are <%= $one %> and <%= $two %>.

更多有关模板的信息可以看看 "Embedded Perl" in Mojolicious::Guides::Rendering.

HTTP 相关的对象

"req" in Mojolicious::Controller"res" in Mojolicious::Controller 的对象调用提供了全功能的 HTTP 的支持.

use Mojolicious::Lite;

# 访问请求的信息, 通过 req 的对象.
get '/agent' => sub {
  my $c = shift;
  my $host = $c->req->url->to_abs->host;
  my $ua   = $c->req->headers->user_agent;
  $c->render(text => "Request by $ua reached $host.");
};

# 通过 res 这个对象定制输出的 header.
post '/echo' => sub {
  my $c = shift;
  $c->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
  $c->render(data => $c->req->body);
};

app->start;

您可以直接从使用命令行测试,这个高级的例子如下

$ ./myapp.pl get -v -M POST -c 'test' /echo

内置异常 exception 和 not_found 网页

在开发的时候, 有时会因为我们的一些错误我们需要用到这些网页, 这个中包含着很多有利于我们 debug 的信息.

use Mojolicious::Lite;

# Not found (404)
get '/missing' => sub { shift->render('does_not_exist') };

# Exception (500)
get '/dies' => sub { die 'Intentional error' };

app->start;

你还可以在命令行下使用 Mojolicious::Command::get 加上 CSS 选择器来导入你感兴趣的信息.

$ ./myapp.pl get /dies '#error'

Route 关联名称

全部的 Routes 会关联到指定的相关的名字, 会自动的取得相关的名字的模板. 这个名字, 可以直接在 "url_for" in Mojolicious::Controller"link_to" in Mojolicious::Plugin::TagHelpers 中使用, 可以很方便的帮到你.

use Mojolicious::Lite;

# /
get '/' => sub {
  my $c = shift;
  $c->render;
} => 'index';

# /hello
get '/hello';

app->start;
__DATA__

@@ index.html.ep
<%= link_to Hello  => 'hello' %>.
<%= link_to Reload => 'index' %>.

@@ hello.html.ep
Hello World!

Layouts

模板是可以设计成组件来布局, 你只需要选择 helper 中的 "layout" in Mojolicious::Plugin::DefaultHelpers. 通过 "content" in Mojolicious::Plugin::DefaultHelpers 给结果放到模板.

use Mojolicious::Lite;

# /with_layout
get '/with_layout' => sub {
  my $c = shift;
  $c->render('with_layout');
};

app->start;
__DATA__

@@ with_layout.html.ep
% title 'Green';
% layout 'green';
Hello World!

@@ layouts/green.html.ep
<!DOCTYPE html>
<html>
  <head><title><%= title %></title></head>
  <body><%= content %></body>
</html>

有 layout 中你可以使用 stash 或者 helpers 来给一些附加的数据放进来, 就象上面使用的 "title" in Mojolicious::Plugin::DefaultHelpers .

模板中的代码块

模板技术中, 可以使用 beginend 的关键字分隔成的代码块来做成象 Perl 本身一样的函数. 以方便在模板技术中重用.

use Mojolicious::Lite;

# /with_block
get '/with_block' => 'block';

app->start;
__DATA__

@@ block.html.ep
% my $link = begin
  % my ($url, $name) = @_;
  Try <%= link_to $url => begin %><%= $name %><% end %>.
% end
<!DOCTYPE html>
<html>
  <head><title>Sebastians frameworks</title></head>
  <body>
    %= $link->('http://mojolicio.us', 'Mojolicious')
    %= $link->('http://catalystframework.org', 'Catalyst')
  </body>
</html>

Helpers

你可以在 Mojolicious 中通过自己的 helper 来扩展应用, 全部的原生的 helper 可以查看 Mojolicious::Plugin::DefaultHelpersMojolicious::Plugin::TagHelpers.

use Mojolicious::Lite;

# A helper to identify visitors
helper whois => sub {
  my $c  = shift;
  my $agent = $c->req->headers->user_agent || 'Anonymous';
  my $ip    = $c->tx->remote_address;
  return "$agent ($ip)";
};

# Use helper in action and template
get '/secret' => sub {
  my $c = shift;
  my $user = $c->whois;
  $c->app->log->debug("Request from $user.");
};

app->start;
__DATA__

@@ secret.html.ep
We know who you are <%= whois %>.

占位符

路径选择的占位符可以让你取得一些请求中的路径的参数. 结果会可以通过 "stash" in Mojolicious::Controller"param" in Mojolicious::Controller 来访问.

use Mojolicious::Lite;

# /foo/test
# /foo/test123
get '/foo/:bar' => sub {
  my $c = shift;
  my $bar  = $c->stash('bar');
  $c->render(text => "Our :bar placeholder matched $bar");
};

# /testsomething/foo
# /test123something/foo
get '/(:bar)something/foo' => sub {
  my $c = shift;
  my $bar  = $c->param('bar');
  $c->render(text => "Our :bar placeholder matched $bar");
};

app->start;

松懈占位符

松懈占位可以让你匹配直接到 / .

use Mojolicious::Lite;

# /test/hello
# /test123/hello
# /test.123/hello
get '/#you/hello' => 'groovy';

app->start;
__DATA__

@@ groovy.html.ep
Your name is <%= $you %>.

通配位符

配位符可以匹配到任何东西, 包括 /..

use Mojolicious::Lite;

# /hello/test
# /hello/test123
# /hello/test.123/test/123
get '/hello/*you' => 'groovy';

app->start;
__DATA__

@@ groovy.html.ep
Your name is <%= $you %>.

HTTP 方法

路径选择器可以通过指定 HTTP 的方法来限定.

use Mojolicious::Lite;

# GET /hello
get '/hello' => sub {
  my $c = shift;
  $c->render(text => 'Hello World!');
};

# PUT /hello
put '/hello' => sub {
  my $c = shift;
  my $size = length $c->req->body;
  $c->render(text => "You uploaded $size bytes to /hello.");
};

# GET|POST|PATCH /bye
any [qw(GET POST PATCH)] => '/bye' => sub {
  my $c = shift;
  $c->render(text => 'Bye World!');
};

# * /whatever
any '/whatever' => sub {
  my $c   = shift;
  my $method = $c->req->method;
  $c->render(text => "You called /whatever with $method.");
};

app->start;

可选的占位符

全部的占位符都需要一个值, 但我们可以通过分配一个默认值, 让占位符的捕获是可选的. 默认的值会简单的和取到的值进行合并在存储在 stash 中. 可选的占位符.

use Mojolicious::Lite;

# /hello
# /hello/Sara
get '/hello/:name' => {name => 'Sebastian', day => 'Monday'} => sub {
  my $c = shift;
  $c->render('groovy', format => 'txt');
};

app->start;
__DATA__

@@ groovy.txt.ep
My name is <%= $name %> and it is <%= $day %>.

限制性占位符

有个最简单的方法, 让你的占位符有严格的范围, 您只需写出可能值的列表.

use Mojolicious::Lite;

# /test
# /123
any '/:foo' => [foo => [qw(test 123)]] => sub {
  my $c = shift;
  my $foo  = $c->param('foo');
  $c->render(text => "Our :foo placeholder matched $foo");
};

app->start;

所有的占位符被编译到成正则表达式, 所以在这也可以很容易地定制你的这个.

use Mojolicious::Lite;

# /1
# /123
any '/:bar' => [bar => qr/\d+/] => sub {
  my $c = shift;
  my $bar  = $c->param('bar');
  $c->render(text => "Our :bar placeholder matched $bar");
};

app->start;

只要确保不使用 ^$ 还有捕获组 (...), 因为这些占位符会和内置的组成一个更大的正则表达式.

Under

通过共享代码进行认证, 在多个路径层次之间很容易实现, 只需要桥接生成的路由并使用 under 的声明. 判断是否是认证通过的路径选择器, 只需要看看返回是否为 true 就知道了.

use Mojolicious::Lite;

# Authenticate based on name parameter
under sub {
  my $c = shift;

  # Authenticated
  my $name = $c->param('name') || '';
  return 1 if $name eq 'Bender';

  # Not authenticated
  $c->render('denied');
  return undef;
};

# / (with authentication)
get '/' => 'index';

app->start;
__DATA__;

@@ denied.html.ep
You are not Bender, permission denied.

@@ index.html.ep
Hi Bender.

要实现相同前缀的多个路径选择器, 也是一个使用的 under 的好理由.

use Mojolicious::Lite;

# /foo
under '/foo';

# /foo/bar
get '/bar' => {text => 'foo bar'};

# /foo/baz
get '/baz' => {text => 'foo baz'};

# /
under '/' => {message => 'whatever'};

# /bar
get '/bar' => {inline => '<%= $message %> works'};

app->start;

你也可以使用 group 来组织相关的 routes , 这可以对多个路径进行 under 的声明.

use Mojolicious::Lite;

# Global logic shared by all routes
under sub {
  my $c = shift;
  return 1 if $c->req->headers->header('X-Bender');
  $c->render(text => "You're not Bender.");
  return undef;
};

# Admin section
group {

  # Local logic shared only by routes in this group
  under '/admin' => sub {
    my $c = shift;
    return 1 if $c->req->heaers->header('X-Awesome');
    $c->render(text => "You're not awesome enough.");
    return undef;
  };

  # GET /admin/dashboard
  get '/dashboard' => {text => 'Nothing to see here yet.'};
};

# GET /welcome
get '/welcome' => {text => 'Hi Bender.'};

app->start;

输出格式 ( 请求后缀 )

这其实是指的后缀, 这个会自动根据后缀来选择.

use Mojolicious::Lite;

# /detection.html
# /detection.txt
get '/detection' => sub {
  my $c = shift;
  $c->render('detected');
};


app->start;
__DATA__

@@ detected.html.ep
<!DOCTYPE html>
<html>
  <head><title>Detected</title></head>
  <body>HTML was detected.</body>
</html>

@@ detected.txt.ep
TXT was detected.

限制性的的占位符也可以使用.

use Mojolicious::Lite;

# /hello.json
# /hello.txt
get '/hello' => [format => [qw(json txt)]] => sub {
  my $c = shift;
  return $c->render_json({hello => 'world'})
    if $c->stash('format') eq 'json';
  $c->render_text('hello world');
};

app->start;

你也可以禁用格式检查.

use Mojolicious::Lite;

# /hello
get '/hello' => [format => 0] => {text => 'No format detection.'};

# Disable detection and allow the following routes selective re-enabling
under [format => 0];

# /foo
get '/foo' => {text => 'No format detection again.'};

# /bar.txt
get '/bar' => [format => 'txt'] => {text => ' Just one format.'};

app->start;

内容协商

不同的表示方法和需要使用 RESTful 的来协商时, 你可以看看 "respond_to" in Mojolicious::Controller.

use Mojolicious::Lite;

# /hello (Accept: application/json)
# /hello (Accept: application/xml)
# /hello.json
# /hello.xml
# /hello?format=json
# /hello?format=xml
get '/hello' => sub {
  my $c = shift;
  $c->respond_to(
    json => {json => {hello => 'world'}},
    xml  => {text => '<hello>world</hello>'},
    any  => {data => '', status => 204}
  );
};

app->start;

有关 MIME type 的相关后缀的对应关系看 "types" in Mojolicious.

app->types->type(rdf => 'application/rdf+xml');

静态文件

和模板技术一样, 只是静态文件可以是单个文件, 也可以从内部 DATA 的部分 ( 可以是 Base64 的编码 ).

use Mojolicious::Lite;

app->start;
__DATA__

@@ something.js
alert('hello!');

@@ test.txt (base64)
dGVzdCAxMjMKbGFsYWxh

外部静态文件不限于一个单独的文件, 如果存在 public 会自动从这个下面查找所需要的文件.

$ mkdir public
$ mv something.js public/something.js
$ mv mojolicious.tar.gz public/mojolicious.tar.gz

外部模板

外部模板会从你的应用目录中的 templates 目录中来查找, 如果不存在就会查找你的 DATA 块中是否存在.

use Mojolicious::Lite;

# /external
any '/external' => sub {
  my $c = shift;

  # templates/foo/bar.html.ep
  $c->render('foo/bar');
};

app->start;

Conditions

条件可以是象 agenthost 之类的信息, 是从 Mojolicious::Plugin::HeaderCondition 中来的东西.可以提供强大的路由限制.

use Mojolicious::Lite;

# /foo (Firefox)
get '/foo' => (agent => qr/Firefox/) => sub {
  my $c = shift;
  $c->render(text => 'Congratulations, you are using a cool browser.');
};

# /foo (Internet Explorer)
get '/foo' => (agent => qr/Internet Explorer/) => sub {
  my $c = shift;
  $c->render(text => 'Dude, you really need to upgrade to Firefox.');
};

# http://mojolicio.us/bar
get '/bar' => (host => 'mojolicio.us') => sub {
  my $c = shift;
  $c->render(text => 'Hello Mojolicious.');
};

app->start;

Sessions

签名 cookie 基于你的 session , 这个原生可以使用.直接通过 "session" in Mojolicious::Plugin::DefaultHelpers 这个来访问到, 所以的全部的 session 的数据序列化是通过 Mojo::JSON 实现的.

use Mojolicious::Lite;

get '/counter' => sub {
  my $c = shift;
  $c->session->{counter}++;
};

app->start;
__DATA__

@@ counter.html.ep
Counter: <%= session 'counter' %>

需要注意的是, 你应该使用一个自定义的 "secret" in Mojolicious 来签署 Cookie 才会真正的安全.

app->secrets(['My secret passphrase here']);

File uploads

所有上传的文件只要是 multipart/form-data 的请求会自动转为 Mojo::Upload 对象处理. 你不用担心内存的使用, 因为超过 250KB 的所有文件将被自动到一个临时文件.

use Mojolicious::Lite;

# Upload form in DATA section
get '/' => 'form';

# Multipart upload handler
post '/upload' => sub {
  my $c = shift;

  # Check file size
  return $c->render(text => 'File is too big.', status => 200)
    if $c->req->is_limit_exceeded;

  # Process uploaded file
  return $c->redirect_to('form')
    unless my $example = $c->param('example');
  my $size = $example->size;
  my $name = $example->filename;
  $c->render(text => "Thanks for uploading $size byte file $name.");
};

app->start;
__DATA__

@@ form.html.ep
<!DOCTYPE html>
<html>
  <head><title>Upload</title></head>
  <body>
    %= form_for upload => (enctype => 'multipart/form-data') => begin
      %= file_field 'example'
      %= submit_button 'Upload'
    % end
  </body>
</html>

为了保护您避免过大的文件, 这也有一个默认极限的值 10MB.你可以使用 "max_message_size" in Mojo::Message 或者 MOJO_MAX_MESSAGE_SIZE 的环境变量来调整这个.

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

User agent

使用 Mojo::UserAgent , 可以通过 "ua" in Mojolicious::Plugin::DefaultHelpers 这个 helper, 它是一个全功能的 HTTP 和 WebSocket 的用户代理, 当你使用 Mojo::JSONMojo::DOM 组合使用时非常的强大.

use Mojolicious::Lite;

# Blocking
get '/headers' => sub {
  my $c = shift;
  my $url  = $c->param('url') || 'http://mojolicio.us';
  my $dom  = $c->ua->get($url)->res->dom;
  $c->render(json => [$dom->find('h1, h2, h3')->text->each]);
};

# Non-blocking
get '/title' => sub {
  my $c = shift;
  $c->ua->get('mojolicio.us' => sub {
    my ($ua, $tx) = @_;
    $c->render(data => $tx->res->dom->at('title')->text);
  });
};

# Concurrent non-blocking
get '/titles' => sub {
  my $c = shift;
  my $delay = Mojo::IOLoop->delay(sub {
    my ($delay, @titles) = @_;
    $c->render(json => \@titles);
  });
  for my $url ('http://mojolicio.us', 'https://metacpan.org') {
    my $end = $delay->begin(0);
    $c->ua->get($url => sub {
      my ($ua, $tx) = @_;
      $end->($tx->res->dom->html->head->title->text);
    });
  }
};

app->start;

更多用法请看 "USER AGENT" in Mojolicious::Guides::Cookbook.

WebSockets

WebSocket 的应用程序从未如此简单. 接收信息通过 "on" in Mojolicious::Controller 中的事件订阅 "json" in Mojo::Transaction::WebSocket. 并通过 "send" in Mojolicious::Controller 返回就行了.

use Mojolicious::Lite;

websocket '/echo' => sub {
  my $c = shift;
  $c->on(json => sub {
    my ($c, $hash) = @_;
    $hash->{msg} = "echo: $hash->{msg}";
    $c->send({json => $hash});
  });
};

get '/' => 'index';

app->start;
__DATA__

@@ index.html.ep
<!DOCTYPE html>
<html>
  <head>
    <title>Echo</title>
    <script>
      var ws = new WebSocket('<%= url_for('echo')->to_abs %>');
      ws.onmessage = function (event) {
        document.body.innerHTML += JSON.parse(event.data).msg;
      };
      ws.onopen = function (event) {
        ws.send(JSON.stringify({msg: 'I ♥ Mojolicious!'}));
      };
    </script>
  </head>
</html>

更我相关的信息可以查看 "REAL-TIME WEB" in Mojolicious::Guides::Cookbook.

模式

你可以通过 Mojo::Log 中的 "log" in Mojo 方法收集调试信息, 并通过 Mojolicious 修改模式为 production 来禁用这个. 也可以通过 "mode" in Mojolicious 来取到属性.

use Mojolicious::Lite;

# Prepare mode specific message during startup
my $msg = app->mode eq 'development' ? 'Development!' : 'Something else!';

get '/' => sub {
  my $c = shift;
  $c->app->log->debug('Rendering mode specific message.');
  $c->render(text => $msg);
};

app->log->debug('Starting application.');
app->start;

默认模式是使用的 development. 这个可以通过命令行参数或者 MOJO_MODE and PLACK_ENV 的环境变量的值来修改它, 模式修改的其它改变是日志级别由 debug 变成 info.

$ ./myapp.pl daemon -m production

全部的日志信息默认会写到标准输出或者如果存在 log 目录就会写到 log/$mode.log 中.

$ mkdir log

模式的改变, 这也会影响到模板其它的地方, 如 exceptionnot_found 的模板.

Testing

创建一个 t 目录和进行 Perl 的单元测试, 测试您的应用程序在这也一样简单.

use Test::More;
use Test::Mojo;

use FindBin;
require "$FindBin::Bin/../myapp.pl";

my $t = Test::Mojo->new;
$t->get_ok('/')->status_is(200)->content_like(qr/Funky/);

done_testing();

使用 Mojolicious::Command::test 命令运行全部的单元测试.

$ ./myapp.pl test
$ ./myapp.pl test -v

如果你想你的测试报告更加多的信息, 你也可以直接在您的测试文件中更改该应用程序的日志级别.

$t->app->log->level('debug');

更多

你接下来可以看 Mojolicious::Guides .

功能

Mojolicious::Lite 实现了下列的功能.

any

my $route = any '/:foo' => sub {...};
my $route = any '/:foo' => {foo => 'bar'} => sub {...};
my $route = any '/:foo' => [foo => qr/\w+/] => sub {...};
my $route = any [qw(GET POST)] => '/:foo' => sub {...};

"any" in Mojolicious::Routes::Route 生成的路由, 会匹配所有的 http 请求.

app

my $app = app;

这是 Mojolicious::Lite 的应用的对象本身.

del

my $route = del '/:foo' => sub {...};
my $route = del '/:foo' => {foo => 'bar'} => sub {...};
my $route = del '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "delete" in Mojolicious::Routes::Route route , 只对 DELETE 的请求有效, 以看详细教程的参数.

get

my $route = get '/:foo' => sub {...};
my $route = get '/:foo' => {foo => 'bar'} => sub {...};
my $route = get '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "get" in Mojolicious::Routes::Route 的 route , 只对 GET 的请求有效, 以看详细教程的参数.

group

group {...};

创建一个新的 route 组.

helper

helper foo => sub {...};

增加一个新的 "helper" in Mojolicious.

hook

hook after_dispatch => sub {...};

使用 "hook" in Mojolicious 共享你的功能.

options

my $route = options '/:foo' => sub {...};
my $route = options '/:foo' => {foo => 'bar'} => sub {...};
my $route = options '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "options" in Mojolicious::Routes::Route 的 route , 只对 OPTIONS 的请求有效, 以看详细教程的参数.

patch

my $route = patch '/:foo' => sub {...};
my $route = patch '/:foo' => {foo => 'bar'} => sub {...};
my $route = patch '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "patch" in Mojolicious::Routes::Route 的路径, 只对 PATCH 的请求有效, 以看详细教程的参数.

plugin

plugin SomePlugin => {foo => 23};

加载插件 "plugin" in Mojolicious.

post

my $route = post '/:foo' => sub {...};
my $route = post '/:foo' => {foo => 'bar'} => sub {...};
my $route = post '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "post" in Mojolicious::Routes::Route 的 route, 只对 POST 的请求有效, 可以看详细教程的参数.

put

my $route = put '/:foo' => sub {...};
my $route = put '/:foo' => {foo => 'bar'} => sub {...};
my $route = put '/:foo' => [foo => qr/\w+/] => sub {...};

生成 "put" in Mojolicious::Routes::Route 的 route , 只对 PUT 的请求有效, 可以看详细教程的参数.

under

my $bridge = under sub {...};
my $bridge = under '/:foo' => sub {...};
my $bridge = under '/:foo' => [foo => qr/\w+/];
  my $bridge = under {format => 0};

通过 "under" in Mojolicious::Routes::Route 生成桥接的路由, 主要用来转发路径选择并自动的附加上前面的, 用于前缀选择之类.

websocket

my $route = websocket '/:foo' => sub {...};
my $route = websocket '/:foo' => {foo => 'bar'} => sub {...};
my $route = websocket '/:foo' => [foo => qr/\w+/] => sub {...};

通过 "websocket" in Mojolicious::Routes::Route 来生成路径选择, 只匹配 WebSocket 的握手.

属性

Mojolicious::Lite 继承全部的属性从 Mojolicious.

方法

Mojolicious::Lite 继承全部的方法从 Mojolicious.

SEE ALSO

Mojolicious, Mojolicious::Guides, http://mojolicio.us.