Mojolicious::Guides::Tutorial - Mojoliciousをはじめよう
説明
Mojolicious::Liteの特徴を簡単なサンプルで紹介していきます。 ここで学んだことは、ほとんどすべてがフルバージョンのMojoliciousアプリケーションにも当てはまります。
チュートリアルはMojolicious::Guidesのはじめの章です。その他のガイドでは、各トピックについて深く掘り下げます。たとえば、Mojolicious::Liteのプロトタイプをしっかり構築したMojolicious アプリケーションに育てるためのgrowing、またはrouting、 rendering、その他にもたくさんあります。これを読み終わった後は、残りのガイドを読むことををおすすめします。
Hello World!
かんたんなHello Worldアプリケーションはこのようになります。strict
,
warnings
,
utf8
、Perl 5.10のfeatures|feature
が自動的に有効になり、 Mojolicious::Liteのfunctions
がいくつかインポートされます。 Mojolicious::Liteを使うと、あなたのスクリプトは完全な機能を備えたウェブアプリケーションになります。
#!/usr/bin/env perl use Mojolicious::Lite; get '/' => sub { my $c = shift; $c->render(text => 'Hello World!'); }; app->start;
Mojolicious::Command::Author::generate::lite_app には、小さなアプリケーションサンプルを生成するためのヘルパーコマンドがあります。
$ mojo generate lite_app myapp.pl
コマンド
多くのcommands が自動的にコマンドラインから利用できるようになります。CGIまたはPSGI のどちらの環境であるかは自動的に検知されるため、通常はコマンドで指定しなくても動作します。
$ ./myapp.pl daemon Server available at http://127.0.0.1:3000. $ ./myapp.pl daemon --listen http://*:8080 Server available at http://127.0.0.1:8080. $ ./myapp.pl cgi ...CGI output... $ ./myapp.pl get / Hello World! $ ./myapp.pl ...利用可能なコマンドが表示(または自動的に環境が検知される)...
Mojoliciousのstart
(app->start
)を呼び出すと、コマンドシステムが開始されます。この呼び出しはアプリケーションの最後に置くべきです。というのは、返り値が大きな影響をもつ場合があるからです。
# @ARGVを使ってコマンドを取得する app->start; # "daemon"コマンドを開始する app->start('daemon', '-l', 'http://*:8080');
リロード
開発用サーバーのmorbo
でアプリケーションを起動すれば、 アプリケーションは自動的にリロードされます。ソースコードを変更した後に毎回サーバを再起動させる必要はありません。
$ morbo myapp.pl Server available at http://127.0.0.1:3000.
アプリケーションのデプロイ方法について詳しい情報は、 Mojolicious::Guides::Cookbookのデプロイメント
の項目を見てください。
ルーティング(Routes)
ルーティング(routes)とは、一般的にいうと異なる種類のプレースホルダを含むことのできる仮想的なパスのことです。通常はアクションにつながっており、リクエストURLのパス部分にマッチしたときに実行されます。すべてのアクション($self
)に渡される第一引数は、Mojolicious::Controllerのインスタンスです。これにはHTTPリクエストとレスポンスが含まれています。
use Mojolicious::Lite; # テキストをレンダリングするアクションへのルーティング get '/foo' => sub { my $c = shift; $c->render(text => 'Hello World!'); }; app->start;
レスポンスコンテントの多くは Mojolicious::Controllerのrender
を使ったアクションによって生成されます。詳しくは後ほど。
GET/POSTパラメーター
すべてのGET
とPOST
パラメーターはMojolicious::Controllerのparam
を通じてアクセスできます。
use Mojolicious::Lite; # /foo?user=sri get '/foo' => sub { my $c = shift; my $user = $c->param('user'); $c->render(text => "Hello $user."); }; app->start;
スタッシュとテンプレート
Mojolicious::Controller のstash
はデータをテンプレートに渡すために利用します。テンプレートはDATA
セクションに埋め込むことができます。template
、text
、data
などのいくつかがスタッシュの値として予約されており、Mojolicious::Controllerのrender
で使われて、レスポンスをどのように生成するかが決定されます。
use Mojolicious::Lite; # テンプレートを描画するアクションに至るルート get '/foo' => sub { my $c = shift; $c->stash(one => 23); $c->render(template => 'magic', two => 24); }; app->start; __DATA__; @@ magic.html.ep The magic numbers are <%= $one %> and <%= $two %>.
テンプレートについて詳しい情報は Mojolicious::Guides::Renderingの埋め込みPerl
の項を見てください。
HTTP
Mojolicious::Controllerのreq
とMojolicious::Controllerのres
を使って、HTTPの機能と情報のすべてに完全にアクセスすることができます。
use Mojolicious::Lite; # リクエストの情報にアクセス 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."); }; # リクエストボディをエコーして、レスポンスのついたカスタムヘッダを送信 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;
Mojolicious::Command::getを使って、 コマンドラインからより発展的なサンプルをテストできます。
$ ./myapp.pl get -v -M POST -c 'test' /echo
JSON
JSONは、ウェブサービスでもっともよく使われるデータ交換フォーマットです。 MojoliciousはJSONが大好きです。ピュアPerlの実装ではおそらく最速の Mojo::JSON が組み込まれており、Mojo::Messageのjson
または予約済みスタッシュ値のjson
によってアクセスできます。
use Mojolicious::Lite; # 受け取ったJSONドキュメントを変更して返す put '/reverse' => sub { my $c = shift; my $hash = $c->req->json; $hash->{message} = reverse $hash->{message}; $c->render(json => $hash); }; app->start;
コマンドラインからMojolicious::Command::getを使ってJSONドキュメントを送信できます。
$ ./myapp.pl get -M PUT -c '{"message":"Hello Mojo!"}' /reverse
組み込みの例外(exception
)とノットファウンド(not_found
)ページ
開発中、間違いを犯したときはいつでも、 このページに遭遇するでしょう。ここには、素晴らしい、アプリケーションのデバックに役立つ 情報がたくさん含まれています。
use Mojolicious::Lite; # Not found (404) get '/missing' => sub { shift->render(template => 'does_not_exist') }; # Exception (500) get '/dies' => sub { die 'Intentional error' }; app->start;
Mojolicious::Command::get でCSSセレクタを使えば、実際に知りたい情報だけを取り出すこともできます。
$ ./myapp.pl get /dies '#error'
ページに情報が見えすぎるからといって心配しないでください。これが有効になるのは開発中だけです。プロダクション環境では、大切な情報が表示されないページに自動的に置き換わります。
ルーティング名
すべてのルーティング(routes)には名前を付けることができます。名前を付けることによってテンプレートの自動検出やMojolicious::Controllerのurl_for
による逆引きができるようになり、Mojolicious::Plugin::TagHelpersのlink_to
など、多くのヘルパーやメソッドがこれに基づいて動きます。
use Mojolicious::Lite; # "index.html.ep"というテンプレートを描画 get '/' => sub { my $c = shift; $c->render; } => 'index'; # "hello.html.ep"というテンプレートを描画 # "hello.html.ep"というテンプレートを描画 app->start; __DATA__; __DATA__; __DATA__; <%= link_to Reload => 'index' %>. @@ hello.html.ep Hello World!
名前がないルートには、自動生成されたルート名が割り当てられます。この名前は、ルート自身の名前からノンワード文字を除いたものと同じです。
レイアウト
テンプレートにはレイアウトを持たせることができます。レイアウトはMojolicious::Plugin::DefaultHelpersのlayout
ヘルパーを使って選択することができ、Mojolicious::Plugin::DefaultHelpersのcontent
ヘルパーを使って現在のテンプレートの結果を入れることができます。
use Mojolicious::Lite; get '/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>
スタッシュやMojolicious::Plugin::DefaultHelpersのtitle
のようなヘルパーを使うと、追加のデータをレイアウトに渡せます。
ブロック
テンプレートブロックは通常のPerl関数のように利用でき、常にbegin
とend
というキーワードで区切ります。これは多くのヘルパーの基盤になっています。
use Mojolicious::Lite; use Mojolicious::Lite; 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://mojolicious.org', 'Mojolicious') %= $link->('http://catalystframework.org', 'Catalyst') </body> </html>
ヘルパー
ヘルパーは Mojolicious::Liteのhelper
キーワードで作ることができる小さな関数です。アクションからテンプレートまでアプリケーション全体において利用することができます。
use Mojolicious::Lite; # 訪問者を特定するヘルパー helper whois => sub { my $c = shift; my $agent = $c->req->headers->user_agent || 'Anonymous'; my $ip = $c->tx->remote_address; return "$agent ($ip)"; }; # アクションとテンプレートのなかでヘルパーを使う 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 %>.
すべての組み込みヘルパーのリストは、 Mojolicious::Plugin::DefaultHelpers と Mojolicious::Plugin::TagHelpersにあります。
プレースホルダー
ルーティング(routes)プレースホルダを使用すると、区切り文字の / あるいは . が出現するまでの部分を、リクエストパスからキャプチャできます。結果はMojolicious::Controllerのstash
とparam
を通じて利用できます。
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; use Mojolicious::Lite; # /hello/test.html get '/hello/*you' => 'groovy'; app->start; __DATA__; __DATA__; Your name is <%= $you %>.
ワイルドカードプレースホルダー
ワイルドカードプレースホルダを使用すると、/
と.
を含むすべてにマッチさせることができます。正規表現の(.+)
に似ています。
use Mojolicious::Lite; use Mojolicious::Lite; # /hello/test123 # /hello/test.123/test/123 get '/hello/*you' => 'groovy'; app->start; __DATA__; __DATA__; Your name is <%= $you %>.
HTTPメソッド
ルーティングは Mojolicious::Lite/のget
や Mojolicious::Liteのany
といったキーワードによって特定のリクエストメソッドに限定できます。
use Mojolicious::Lite; # "hello.html.ep"というテンプレートを描画 # "hello.html.ep"というテンプレートを描画 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 ['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;
プレースホルダーのオプション
すべてのプレースホルダーは値を必要としますが、 プレースホルダーにデフォルト値を設定することにより キャプチャをオプショナルなものにすることができます。
use Mojolicious::Lite; # /hello # /hello/Sara get '/hello/:name' => {name => 'Sebastian', day => 'Monday'} => sub { my $c = shift; $c->render(template => 'groovy', format => 'txt'); }; app->start; __DATA__; @@ groovy.txt.ep My name is <%= $name %> and it is <%= $day %>.
プレースホルダーに所属しないデフォルト値は、 いつでも単純にスタッシュにマージされます。
制約的なプレースホルダー
プレースホルダーにより多くの制約を加えるには、選択肢を使うのが一番簡単です。候補となる値のリストを作るだけでOKです。
use Mojolicious::Lite; # /test # /123 any '/:foo' => [foo => ['test', '123']] => sub { my $c = shift; my $foo = $c->param('foo'); $c->render(text => "Our :foo placeholder matched $foo"); }; app->start;
すべてのプレースホルダーは、内部で正規表現にコンパイルされます。この処理はカスタマイズすることもできます。^
と$
を使ったり、(...)
でグループのキャプチャは行わないでください。けれどもキャプチャしない(?:...)
は大丈夫です。
use Mojolicious::Lite; use Mojolicious::Lite; # /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;
生成されたすべての正規表現は、 Mojolicious::Command::routesで詳しく確認することができます。
$ ./myapp.pl routes -v
アンダー (Under)
認証や複数のルーティングの間でコードを共有するためには、Mojolicious::Liteのunder
構文を使う簡単です。以降のすべてのルーティングは、underコールバックが真値を返したときだけ評価されます。
use Mojolicious::Lite; # nameパラメータを元にした認証 # すべてのルートで共有されるグローバルなロジック my $c = shift; # 認証された my $name = $c->param('name') || ''; my $name = $self->param('name') || ''; # 認証されなかった $c->render(template => 'denied'); return undef; }; # / (with authentication) get '/' => 'index'; app->start; __DATA__; __DATA__; You are not Bender, permission denied. __DATA__; Hi Bender.
複数のルーティングをあらかじめ決めるために使うのもまた良い利用方法です。
use Mojolicious::Lite; # /foo under '/foo'; # /foo/bar get '/bar' => {text => 'foo bar'}; # /foo/baz get '/baz' => {text => 'foo baz'}; # / under '/' => {msg => 'whatever'}; # /bar get '/bar' => {inline => '<%= $msg %> works'}; app->start;
Mojolicious::Liteのgroup
で関連するルーティングをグループ化(group
)することもできます。これによって、under
で生成したルートをネストできるようになります。
use Mojolicious::Lite; # すべてのルートで共有されるグローバルなロジック # すべてのルートで共有されるグローバルなロジック my $c = shift; return 1 if $c->req->headers->header('X-Bender'); $c->render(text => "You're not Bender."); return undef; }; # Adminの部分 group { # グループ内のルートだけに共有されるローカルなロジック under '/admin' => sub { my $c = shift; return 1 if $c->req->headers->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;
フォーマット
フォーマット(formats)は、.html
などのファイル拡張子によって自動的に検出されます。フォーマットは正しいテンプレートを探したり、正確なContent-Type
ヘッダーを生成するために使用されます。
use Mojolicious::Lite; use Mojolicious::Lite; # /detection.html # /detection.txt get '/detection' => sub { my $c = shift; $c->render(template => '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.
デフォルトのフォーマットは html
です。プレースホルダで制限すれば、取りうる値を限定できます。
use Mojolicious::Lite; # /hello.json # /hello.txt get '/hello' => [format => ['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.'}; # 検出を無効にして、以降のルートにおいて必要であれば再び有効にする under [format => 0]; # /foo get '/foo' => {text => 'No format detection again.'}; # /bar.txt get '/bar' => [format => 'txt'] => {text => ' Just one format.'}; app->start;
コンテントネゴシエーション
異なる方法で表現されるリソースや本当にRESTfulなコンテントネゴーシエーションが必要な場合は、Mojolicious::Plugin::DefaultHelpersのrespond_to
を使用することもできます。
use Mojolicious::Lite; # /hello (Accept: application/json) # /hello (Accept: application/xml) # /hello.json # /hello.xml # /hello?format=json # /hello?format=xml # "hello.html.ep"というテンプレートを描画 my $c = shift; $c->respond_to( json => {json => {hello => 'world'}}, xml => {text => '<hello>world</hello>'}, any => {data => '', status => 204} ); }; app->start;
MIMEタイプのマッピングは、Mojoliciousのtypes
によって拡張したり、変更したりすることができます。
app->types->type(rdf => 'application/rdf+xml');
静的ファイル
テンプレートに似て、静的ファイルはDATA
セクションの中にインラインで記述することができ、自動的にサーブされます。ただし、使える拡張子が1種類に限られるのと、Base64エンコーディングが使える点が異なります。
use Mojolicious::Lite; app->start; __DATA__; @@ something.js alert('hello!'); @@ test.txt (base64) dGVzdCAxMjMKbGFsYWxh
外部に置いた静的ファイルは、拡張子が1種類に制限されず、public
ディレクトリが存在すればそこから自動的にサーブされます。
$ mkdir public $ mv something.js public/something.js $ mv mojolicious.tar.gz public/mojolicious.tar.gz
両方とも優先度はGET
、HEAD
リクエストのルーティングよりも高くなります。 Range
、If-None-Match
、If-Modified-Since
ヘッダー によるコンテンツネゴシエーションにも対応していて、 Mojolicious::Command::getで簡単にテストできます。
$ ./myapp.pl get /something.js -v -H 'Range: bytes=2-4'
外部テンプレート
外部テンプレートは、レンダラによってtemplates
ディレクトリから検索されます。
$ mkdir -p templates/foo $ echo 'Hello World!' > templates/foo/bar.html.ep
これらはDATA
セクションにあるテンプレートよりも優先されます。
use Mojolicious::Lite; # "templates/foo/bar.html.ep"というテンプレートを描画する any '/external' => sub { my $c = shift; $c->render(template => 'foo/bar'); }; app->start;
ホーム
Mojoliciousのhome
を使うと、アプリケーションがホームとしているディレクトリにアクセスできます。ホームディレクトリは、アプリケーションがpublic, templatesディレクトリを検索する場所です。ここにあらゆる種類のアプリケーションデータを保存することもできます。
$ mkdir cache $ echo 'Hello World!' > cache/hello.txt
Mojo::Home には Mojo::Fileから継承した便利なメソッドがたくさんあります。たとえば、Mojo::Fileのchild
やslurp
は、アプリケーションを様々なオペレーティングシステムにまたがって使用できるようにしています。
use Mojolicious::Lite; # メッセージをメモリに読み込む my $hello = app->home->child('cache', 'hello.txt')->slurp; # メッセージを表示する get '/' => sub { my $c = shift; $c->render(text => $hello); };
Mojolicious::Command::eval を使うことでも、コマンドラインからアプリケーションを検証できます。
$ ./myapp.pl eval -v 'app->home'
条件
Mojolicious::Plugin::HeaderCondition のagent
やhost
といった条件 を使用すれば、より強力なルーティングを構築できます。
use Mojolicious::Lite; # Firefox get '/foo' => (agent => qr/Firefox/) => sub { my $c = shift; $c->render(text => 'Congratulations, you are using a cool browser.'); }; # Internet Explorer get '/foo' => (agent => qr/Internet Explorer/) => sub { my $c = shift; $c->render(text => 'Dude, you really need to upgrade to Firefox.'); }; # http://mojolicious.org/bar get '/bar' => (host => 'mojolicious.org') => sub { my $c = shift; $c->render(text => 'Hello Mojolicious.'); }; app->start;
セッション
Mojolicious::Plugin::DefaultHelpersのsession
ヘルパーを使うとすぐに、クッキーをベースとしたセッションが機能します。すべてのセッションデータはMojo::JSONでシリアライズされ、 クライアントサイドに保存されることを意識しておいてください。改ざんを防ぐために、暗号化された署名がついています。
use Mojolicious::Lite; # アクションとテンプレートの中のセッションデータへのアクセス get '/counter' => sub { my $c = shift; $c->session->{counter}++; }; app->start; __DATA__; __DATA__; Counter: <%= session 'counter' %>
署名付き(signed)クッキーを本当に改ざんできなくするには、Mojoliciousのsecret
をカスタムして使用してください。
app->secrets(['My secret passphrase here']);
ファイルアップロード
ファイルは、multipart/form-data
リクエストを通してアップロードされると、自動的に Mojolicious::Controllerのparam
からMojo::Uploadのインスタンスとして利用可能になります。 メモリの使用率を気にする必要はありません。250KB
を超えるすべてのファイルは自動的に一時ファイルに保存されるからです。HTMLフォームを効率的に構築するために、 Mojolicious::Plugin::TagHelpersのform_for
のような タグヘルパーを使うこともできます。
use Mojolicious::Lite; # DATAセクションのformをアップロード get '/' => 'form'; # Multipartのアップロードのハンドラ post '/upload' => sub { my $c = shift; # ファイルサイズのチェック return $c->render(text => 'File is too big.', status => 200) if $c->req->is_limit_exceeded; # アップロードしたファイルを処理 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>
極端に大きなファイルから保護するために、デフォルトで16MB
の制限があります。サイズはMojoliciousのmax_request_size
属性で変更できます。
# 制限を1GBに増やす app->max_request_size(1073741824);
ユーザーエージェント
Mojo::UserAgentは、完全に機能を備えたHTTP 1.1とWebSocketの組み込みのユーザーエージェントです。Mojolicious::Plugin::DefaultHelpersのua
を通して利用できます。特にMojo::JSONとMojo::DOMの組み合わせはとても強力なツールになります。
use Mojolicious::Lite; # ブロッキング # ブロッキング my $c = shift; my $url = $c->param('url') || 'https://mojolicious.org'; my $dom = $c->ua->get($url)->result->dom; $c->render(json => $dom->find('h1, h2, h3')->map('text')->to_array); }; # ノンブロッキング get '/title' => sub { my $c = shift; $c->ua->get('mojolicious.org' => sub { my ($ua, $tx) = @_; $c->render(data => $tx->result->dom->at('title')->text); }); }; # 並列のノンブロッキング get '/titles' => sub { my $c = shift; my $c = shift; my $cpan = $c->ua->get_p('https://metacpan.org'); Mojo::Promise->all($mojo, $cpan)->then(sub { my ($mojo, $cpan) = @_; $c->render(json => { mojo => $mojo->[0]->result->dom->at('title')->text, cpan => $cpan->[0]->result->dom->at('title')->text }); })->wait; }; app->start;
ユーザーエージェントについてより詳しい情報は、Mojolicious::Guides::Cookbookのユーザーエージェント
の項目にあります。
WebSocket
WebSocketアプリケーションはこれまでに見たこともないくらい簡単です。Mojo::Transaction::WebSocketのjson
と同じイベントを、Mojolicious::Controllerのon
を使って購読することによってメッセージを受信できます。メッセージを送信するには Mojolicious::Controllerのsend
を使います。
use Mojolicious::Lite; use Mojolicious::Lite; my $c = shift; $c->on(json => sub { my ($c, $hash) = @_; my ($self, $hash) = @_; $c->send({json => $hash}); }); }; get '/' => 'index'; app->start; __DATA__; __DATA__; <!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>
リアルタイムウェブ機能についてのより詳しい情報は、Mojolicious::Guides::CookbookのREAL-TIME WEB
にあります。
モード
ポータブルにデバッグメッセージを収集するために、Mojoのlog
メソッドでMojo::Logオブジェクトを利用できます。Mojoliciousの処理モードを変更することによって、後のプロダクション用の設定においてデバッグを自動的に無効化することができます。これはMojoliciousのmode
属性によって読み取り可能です。
use Mojolicious::Lite; # 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
あるいはPLACK_ENV
環境変数によって変更することもできます。development
以外のモードでは、ログレベルがdebug
からinfo
に上がります。
$ ./myapp.pl daemon -m production
すべてのメッセージはSTDERR
に出力されるか、 log
ディレクトリが存在する場合はlog/$mode.log
に出力されます。
$ mkdir log
モードの変更は、exception
やnot_found
テンプレートなどのフレームワークのその他の面に影響します。モードをdevelopment
からproduction
に切り替えると 、例外ページに機密情報が表示されなくなります。
テスト
アプリケーションをテストするのはとても簡単です。t
ディレクトリを作成して 普通のPerlの単体テストを書くだけです。Test::Mojoのおかげで、 とても楽しいです。
use Test::More; use Mojo::File 'path'; use Test::Mojo; # Portably point to "../myapp.pl" my $script = path(__FILE__)->dirname->sibling('myapp.pl'); my $t = Test::Mojo->new($script); $t->get_ok('/')->status_is(200)->content_like(qr/Funky/); done_testing();
テストはprove
で実行します。
$ prove -l -v $ prove -l -v t/basic.t
もっと
さあ、Mojolicious::Guides を続けるか、Mojolicious wikiを見てみましょう。多くの著者がたくさんのドキュメントやサンプルを書いています。
サポート
このドキュメントでわからない部分があれば、 mailing list かirc.freenode.net
(chat now!)の公式IRCチャンネル #mojo
まで気軽に質問してください。
参考
Mojolicious, Mojolicious::Guides, http://mojolicio.us.
(2019/03/16 Mojolicious 8.12)