SlideShare a Scribd company logo
1 of 87
Download to read offline
Mojoliciousでつくる!
Webアプリ入門
2013/09/21
YAPC::Asia 2013
Yusuke Wada a.k.a. yusukebe
Some papix photos are in this slides.Thanks to papix!
イントロダクション
自己紹介
• 和田裕介 1981/12/23 生
• 慶應義塾大学制作メディア研究科修了
• 株式会社ワディット代表取締役
• 株式会社オモロキ取締役兼最高技術責任者
• http://yusukebe.com/ or @yusukebe
メインワーク
問いかけ
Perlは大規模Webサービス
で使われているが...
初心者がWebアプリに入門する資料が少ない...?
あえて去年を振り返る
「新しい」を生み出すためのWebアプリ開発とその周辺
何をつくるかは分かった
そのための
実装について
本日の主題
対象オーディエンス
• Webアプリケーションをつくりたい方
• アイデアはあるが実装できない... って方
• 最近のWAFについて知りたい方
• Web Application Framework = WAF
• Mojoliciousを使った具体的なアプリ構成を
知りたい方
方針
当たり前に使っている概念、実装、キーワード
噛み砕いて解説
=> GoogleやCPANで検索できるように!
実はすごく周辺からは分かりにくい...?
アジェンダ
• 例題:占いアプリについて
• WebアプリケーションとFramework
• Mojoliciousの紹介
• Mojolicious::Liteを使う
• より実践的なアプリへ
• CPANモジュールとの組み合わせと工夫
• 今後へ
0. 例題:占いアプリについて
名前に応じて占い結果を出す
• 占い結果はまず3種類
• 良い事が起こるでしょう
• 出会いがあるかも?
• 不幸になります
• 入力された名前に対して必ず同じ結果
• yusukebe => 「出会いがあるかも?」
ハッシュ関数
my $name = "yusukebe";
my $max = 3;
my $number = 0;
# 文字列を一文字ずつ分解
for my $char (split //, $name) {
# 文字に対応する数値を得る
$number += ord $char;
}
# 想定される最大値で割った余りを得る
my $result = $number % $max;
print "$resultn";
文字列
数値
固定値で割る
余りが結果
スクリプトで実現する
ようは診断メ○カーみたいな?
1. WebアプリケーションとFramework
Webアプリケーションを定義する
Webが誰かと特徴的な
インタラクション
をする場合
Webアプリケーション
Webのインタラクション
Web
アプリケーション
ユーザー
例えば自分の名前を
入力する
占いの結果を見る
JSの動作
外部のWeb API
ミドルウェア etc.
ブラウザ
プログラム
スマホアプリ
Web Application Framework
• 通称 WAF(ワッフ)
• 例えば Ruby on Rails
• Webアプリケーションをつくるための土台
• MVCモデルに基づく場合が多い
MVCってなんぞー?
Model
View
Controller
MVC
MVCである意味は...?
MVC以前
何がイケてないって?
• 色々混じってる
• ヘッダー出力
• ロジック処理
• HTMLの描画
• ファイルごとにルーティングする
• 重複が起こる
*CGIはデプロイ方法の
一つなのでCGI自体が
良くないわけではない
愚直に.cgiを書くと
use CGI qw/param header/;
my $name = param('name');
my @list = qw/良い事が起こるでしょう 出会いがあるかも? 不幸になります/;
my $num = 0;
$num += ord ($_) for split //, $name;
my $index = $num % scalar @list;
my $message = $list[$index];
print header('text/html; charset=utf-8');
print "<html><body>";
print "<center><b>$message</b></center>";
print "</body></html>";
HTMLだけでも分離させると...
use CGI qw/param header/;
use Text::MicroTemplate qw/render_mt/;
use Data::Section::Simple qw/get_data_section/;
my $name = param('name');
my @list = qw/良い事が起こるでしょう 出会いがあるかも? 不幸になります/;
my $num = 0; $num += ord ($_) for split //, $name;
my $index = $num % scalar @list;
my $message = $list[$index];
my $template = get_data_section('index.mt');
my $html = render_mt($template, $message)->as_string();
print header('text/html; charset=utf-8');
print $html;
__DATA__
@@ index.mt
<html>
<body>
<center><b><?= $_[0] ?></b></center>
</body>
</html>
冗長になるが
見通しがよくなる!
さらにテンプレートをファイルに分けると...
メンテナンス性、再利用性の向上
冗長性はフレームワークが吸収してくれる?
とりあえずMVCで考える意味
• 混在している固まりを役割で分ける
• 理解をすれば冗長になるが開発効率が上がる
"分けるとは分かること"
切り分け方
1. Router
2. Controller
3. Model / Logic
4. DB層 / OR Mapper
5. View / Static files
ビジネスロジックを扱う
出力や見た目に関する部分
個別のリクエストに基づく処理
データベースにまつわる
URL/METHODに応じて振り分ける
役割を分けること
=
フレームワーク的思考へ
処理の流れ
Router
Controller
Model / Logic
DB / OR Mapper
View
1. リクエスト
2. ディスパッチ
3. モデル呼び出し
4. DB呼び出し 5. DB結果返却
6. 結果
7. レンダリング
8. HTMLなど
9. レスポンス
PerlのWAF達
• Catalyst
• Dancer
• Amon2
• Kossy
• Pickles
• Voson
• Mojolicious
• 自作WAF
自作WAFと既存WAF
• MVC?を実現するモジュールは揃っている
• Plack::Request
• Router::Simple
• Text::Xslate
• ただアプリを書きながらWAFもはキツい
• 勉強用に車輪の再発明は多いに歓迎
• でもとりあえずWAFを使いましょうね ♥
2. Mojoliciousの紹介
Mojolicious !
• 属に言う「軽量WAF」の一種
• 最新Ver.は「4.35」2013年9月12日時点
• 作者は「Sebastian Riedel」氏
特徴1. VCだけサポート
• Routing / Controller
• デフォルトではMojo::Templateを使うView
• のみサポートし「Model」は対象外
Mojo::Baseその他でクラスつくったりOR Mapper
使ったりして自力で実装してね ♪ っていう...
逆にそれがいい
Model/Logic層はWebから切り離すべき
特徴2. Not full-stack but full-stack
Ruby on Rails
DBを扱うまで全てこれ一つで出来る フルスタック
Mojolicious
HTTPのRequestやUserAgentまで
Mojoliciousで使うライブラリが全て自作
フルスタック
コア以外のCPANモジュールに依存しない!
$ cpanm Mojolicious
Mojoliciousなら一発
特徴3. その他
• アップデートが頻繁
$self->render_json( $ref ); # 4.00 で廃止
# =>
$self->render( json => $ref );
ただし依存が無いのでMojoliciousだけ追っていればよい
• Mojolicious::Lite を使えばファイル一つで
• 工夫すればCGIでも動作可能
• Perl 5.10.1 以上必須、5.16 以上を推奨
• 開発用サーバmorbo、本番用hypnotoad
• もちろんPSGI互換
小さなアプリから大きなWebアプリまで
徐々に学べるフレームワーク
Mojolicious::Lite
Mojolicious
CPANモジュールの組み合わせ
3. Mojolicious::Liteを使う
mojoコマンドによるスケルトン
$ mojo generate lite_app myapp.pl
Mojolicious::Lite
はじめてのMojolicious::Lite
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub {
my $self = shift;
$self->stash->{message} = 'Hello Mojo!';
$self->render('index');
};
app->start;
__DATA__
@@ index.html.ep
<html>
<body>
<p><%= $message %></p>
</body>
</html>
Controllerに該当
View(テンプレート)
Routingしてる
立ち上げ方
$ morbo -l "http://*:5000" myapp.pl
morboを使う
$ plackup -p 5000 myapp.pl
plackupで立ち上げる
Hello World から学ぶ
get '/' => sub {};
ルーティングとコントローラ
GET http://localhost:5000/
get '/entry/:id' => sub {
my $entry_id = $self->stash->{id};
};
post '/entry' => sub {};POST http://localhost:5000/entry
GET http://localhost:5000/entry/1
Hello World から学ぶ
get '/' => sub {
my $self = shift;
$self->stash->{message} = 'Hello Mojo';
...;
}
テンプレートにデータを渡す
$self->render('index'); # index.html.ep を描画
...;
<p><%= $message %></p>
テンプレートの記述とレンダー
もちろん占いアプリも!
Short live coding !?
#!/usr/bin/env perl
use Mojolicious::Lite;
use utf8;
...;
get '/' => sub {
my $self = shift;
$self->render('index');
};
...;
@@ index.html.ep
<p>名前を入力してください</p>
<form action="/result">
<input type="text" name="name" />
<input type="submit" value="占う" />
</form>
トップページを描画
...;
get '/result' => sub {
my $self = shift;
my $name = $self->req->param('name');
my @list
= qw/良い事が起こるでしょう 出会いがあるかも? 不幸になります/;
my $num = 0;
$num += ord ($_) for split //, $name;
my $index = $num % scalar @list;
$self->stash->{message} = $list[$index];
$self->stash->{name} = $name;
$self->render('result');
};
...;
@@ result.html.ep
<p><%= $name %>さんの結果「<%= $message %>」</p>
結果を出力
Controller内での操作
• 全ては「$self」のメソッドを扱う
my $value = $self->req->param('key');
$self->render('entry');
$self->render( json => { key => $value } );
Mojolicious::Controller を継承するのでそのドキュメントを読めばOK!
$self->redirect_to('/');
Mojo::Template周り
• Perl-ish templates => Perl書ける!
% for my $entry (@$entries) {
<h2><%= $entry->{title} %></h2>
% }
Mojo::Template / Mojolicious::Plugin::DefaultHelper
• テンプレート向けhelper
@@ index.html.ep
% layout 'default';
Hi, <%= $name %>
@@ layouts/default.html.ep
<html>
<body><%= content %></body>
</html>
Mojolicious::Liteアプリを拡張する
• public/ => 静的ファイルを置く
• templates/ => テンプレートファイルを独立
./
!"" myapp.pl
!"" public/
#   !"" css/
#   !"" favicon.ico
#   !"" images/
#   %"" js/
%"" templates/
!"" layouts/
#   %"" default.html.ep
%"" root/
%"" index.html.ep
4. より実践的なアプリへ
Mojolicious::Liteだと1ファイルがでかくなるよー
そこで ::Lite じゃないMojoliciousアプリ!
モジュールをいい感じに分けてつくれる
Mojoliciousアプリをつくるコツ
• $ mojo generate app MyApp では無く
MyApp::Web みたいなネームスペースで
$ mojo genearate app Uranai::Web
• なぜならUranaiがWeb層だけではないかも
• Uranai::Model / Uranai::Logic
• Uranai::CLI
だいたいこんな構成
./
!"" Uranai/
#   !"" DB/
#   #   %"" Schema.pm
#   !"" DB.pm
#   !"" Model/
#   #   %"" OneModel.pm
#   !"" Web/
#   #   %"" Controller/
#   #   %"" Root.pm
#   %"" Web.pm
%"" Uranai.pm
DBレイヤー / Teng etc.
ビジネスロジック / Perl Module
Webレイヤー /
主にControllerとルーティング
Uranai.pm では パス解決と設定ロードを実装
::Liteからの移行
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub {
my $self = shift;
$self->stash->{message} = 'Hello Mojo!';
$self->render('index');
};
app->start;
__DATA__
@@ index.html.ep
<html>
<body>
<p><%= $message %></p>
</body>
</html>
lib/Uranai/Web.pm
lib/Uranai/Web/Controller/*
Mojolicious::Controllerを継承
templates/
Mojo::Templateに準ずる
すんなり移行出来る!
占いアプリを実装してみる
実装方針
• 占いのロジック部分をModelとして切り出す
• Uranai::Model::Uranai
• それをControllerから適宜呼び出す
• ViewはMojolicious::Liteと同じものを
別ファイルにする
Uranai::Model::Uranai
package Uranai::Model::Uranai;
use Mouse;
has 'list' => (
is => 'ro',
isa => 'ArrayRef[Str]',
default => sub {
[qw/良い事が起こるでしょう
出会いがあるかも?
不幸になります
/]}
);
sub uranau {
my ($self, $name) = @_;
my $num = 0;
$num += ord ($_) for split //, $name;
my $index = $num % scalar @{$self->list()};
return $self->list->[$index];
}
__PACKAGE__->meta->make_immutable();
ModelはCLIからも使える
use Uranai::Model::Uranai;
use feature 'say';
my $uranai = Uranai::Model::Uranai->new;
say $uranai->uranau('yusukebe');
ってことは単体でテスト出来る!
Uranai::Web::Controller::Root
package Uranai::Web::Controller::Root;
use Mojo::Base 'Mojolicious::Controller';
use Uranai::Model::Uranai;
sub index {
my $self = shift;
$self->render('index');
}
sub result {
my $self = shift;
my $name = $self->req->param('name');
return $self->redirect_to('/') unless $name;
my $uranai = Uranai::Model::Uranai->new;
my $message = $uranai->uranau($name);
$self->stash->{message} = $message;
$self->render('result');
}
1;
アプリをつくるフロー
• Modelを書く
• (テストする)
• Routing / Controller を書く
• テンプレートを書く
• テストサーバを起動しておく
• ブラウザで確認
• 繰り返し...
5. CPANモジュールとの組み合わせと工夫
Mojoliciousだけでは足りない
• CPANモジュールを組み合わせてつくる
• Like LEGO blocks
Mojolicious
OR Mapper FormValidator FillInForm etc.
use FormValidator::Lite;
• 入力値の妥当性をチェックする
• 例:メールアドレス、郵便番号、文字数
FormValidator::Lite->load_constraints(qw/Japanese Email/);
my $validator = FormValidator::Lite->new($self->req);
my $res -> $validator->check(
name => [qw/NOT_NULL/],
mail => [qw/EMAIL/],
{ mails => [qw/mail mail_confirm/] } => ['DUPLICATION']
);
if($validator->has_error) {
$self->stash->{messages} = $validator->get_error_messages();
return $self->render;
}
...;
use Teng;
• データベースを操作する OR Mapper
• とってもシンプル
• Controllerからは操作せずModelから触る
my $teng = Teng::Schema::Loader->load(
dbh => $dbh,
namespace => 'Uranai::DB',
);
my $row = $teng->insert(result => {
text => 'あなたは結婚出来ません',
});
DBを用いた占いアプリの応用
• 固定だった3つの選択肢を増やせるようにしたい
ちなみにやったこと
CREATE TABLE result (
id INT UNSIGNED AUTO_INCREMENT,
text VARCHAR(200) NOT NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY (`id`)
);
1. DBをつくって...
lib/Uranai/DB.pm
lib/Uranai/DB/Schema.pm
2. TengのDB/スキーマつくって...
lib/Uranai/Model/Uranai.pm
3. Modelから操作するようにして...
lib/Uranai/Controller/Root.pm
5. Controllerから呼び出す
templates/root/index.html.ep
6. Viewの変更
t/01_model.t
4. 簡単なテスト書いて...
できた!
その他実践で使ってるモジュール
• HTML::FillInForm::Lite
• Data::Validator
• Mouse
• SQL::Maker
• Carton
• Devel::NYTProf / Devel::KYTProf
• Test::mysqld
• Harriet
• Cinnamon
• Server::Starter
• Starman / Starlet
• etc....
Thanks to great Module Authors !
Tips
DELETE/PUTを擬似的にサポートさせる
$self->hook(
before_dispatch => sub {
my $c = shift;
if($c->req->method eq 'POST' && $c->req->param('_method')) {
my $methods = [qw/GET POST PUT DELETE/];
if ( grep { $_ eq uc $c->req->param('_method') } @$methods ) {
$c->req->method( $c->req->param('_method') );
}
}
}
);
my $r = $self->routes;
$r->delete('/entry/:id')->
to( controller => 'Entry', action => 'delete' );
helperでFillInFormをお手軽に
# Uranai::Web
$self->helper(
render_fill => sub {
my ($self, $name) = @_;
my $html = $self->render(template => $name, partial => 1);
return $self->render(
text => HTML::FillInForm::Lite->fill($html, $self->req->params),
format => 'html'
);
}
);
# Uranai::Web::Controller::*
sub form {
my $self = shift;
...;
if ($validator->error) {
$self->stash->{messages} = $validator->get_error_messages();
return $self->render_fill('form');
}
}
Uranai->config();
# Uranai
sub config {
my $mode = $ENV{PLACK_ENV} || 'development';
my $fname = File::Spec->catfile( Uranai->base_dir() , $mode . '.pl' );
my $config = undef;
if( -f $fname ){
$config = do $fname or die "Cannnot load configuration file: $fname";
}else{
die "Cannot find configuration file: $fname";
}
return $config;
}
Mojoliciousのセッションについて
• デフォルトはクライアントにクッキーとして保持
• 気に入らない場合は...
• Plack::Middleware::Session
• 自作セッション管理
6. 今後へ
紹介したこと
• WAFとMVC的な構成について
• 役割を適切に分けることでスッキリと
• 対応するMojoliciousを使った実装
• 占いアプリを例にあげた
Webアプリをつくるには?
• 例えば今回の占いアプリ
• Mojolicious::Liteで実装してみる
• 出来た!俺ってばスゲー体験 その1
• Mojoliciousアプリで拡張してみる
• 出来た!俺ってばスゲー体験 その2
• Tengを学習し占いのパターンを増やす
• 出来た!俺ってばスゲー体験 その3
俺ってばスゲー体験
少しずつ"動いて" "分かる"
扱わなかった主な点
• よりツッコんだMojoliciousの使い方
• テスト => Test::More / Test::Mojo
• 生に近いDB/SQL操作
• その他ミドルウェア => memcached / Redis
• デプロイ => サーバ構成 / アプリサーバ
• パフォーマンス計測、チューニング
• Perl以外のこと => JavaScript / CSS / HTML
まとめ
Mojoliciousではじめよう
• 薄いWAFゆえ理解しやすい
• Mojolicious::Lite のように少しずつつくれる
• 他のWAFにも応用出来る
徐々に学べるフレームワーク
キーワードは...
分けることで分かる
少しずつやろう
終わり
ご質問は個別に!

More Related Content

What's hot

What's hot (20)

はじめようRGB-Dセンシングと画像処理
はじめようRGB-Dセンシングと画像処理はじめようRGB-Dセンシングと画像処理
はじめようRGB-Dセンシングと画像処理
 
Electron で作るはじめてのguiアプリ
Electron で作るはじめてのguiアプリElectron で作るはじめてのguiアプリ
Electron で作るはじめてのguiアプリ
 
【Unite Tokyo 2019】たのしいDOTS〜初級から上級まで〜
【Unite Tokyo 2019】たのしいDOTS〜初級から上級まで〜【Unite Tokyo 2019】たのしいDOTS〜初級から上級まで〜
【Unite Tokyo 2019】たのしいDOTS〜初級から上級まで〜
 
LinuxでDisplaylinkのディスプレイを使いたい
LinuxでDisplaylinkのディスプレイを使いたいLinuxでDisplaylinkのディスプレイを使いたい
LinuxでDisplaylinkのディスプレイを使いたい
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
 
【Unity道場 博多スペシャル 2017】Textmesh proを使いこなす
【Unity道場 博多スペシャル 2017】Textmesh proを使いこなす【Unity道場 博多スペシャル 2017】Textmesh proを使いこなす
【Unity道場 博多スペシャル 2017】Textmesh proを使いこなす
 
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
 
Unity で実装するエイジングテストのお話
Unity で実装するエイジングテストのお話Unity で実装するエイジングテストのお話
Unity で実装するエイジングテストのお話
 
Jenkins使ってみた~Windows編~
Jenkins使ってみた~Windows編~Jenkins使ってみた~Windows編~
Jenkins使ってみた~Windows編~
 
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
アナザーエデンPC版リリースへの道のり 〜WFSにおけるマルチプラットフォーム対応の取り組み〜
 
UniRxでMV(R)Pパターン をやってみた
UniRxでMV(R)PパターンをやってみたUniRxでMV(R)Pパターンをやってみた
UniRxでMV(R)Pパターン をやってみた
 
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話
 
プラネタリウム映像をUnityで
プラネタリウム映像をUnityでプラネタリウム映像をUnityで
プラネタリウム映像をUnityで
 
Unityではじめるオープンワールド入門 アーティスト編
Unityではじめるオープンワールド入門 アーティスト編Unityではじめるオープンワールド入門 アーティスト編
Unityではじめるオープンワールド入門 アーティスト編
 
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
誰もAddressableについて語らないなら、自分が語るしかない…ッッッッ
 
UIElements+UI BuilderでEditor拡張を作ろう
UIElements+UI BuilderでEditor拡張を作ろうUIElements+UI BuilderでEditor拡張を作ろう
UIElements+UI BuilderでEditor拡張を作ろう
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 

Viewers also liked

Mojolicious::Liteを使ってみよう
Mojolicious::Liteを使ってみようMojolicious::Liteを使ってみよう
Mojolicious::Liteを使ってみよう
charsbar
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてる
jamadam
 
Mojolicious+redisでチャットを作った
Mojolicious+redisでチャットを作ったMojolicious+redisでチャットを作った
Mojolicious+redisでチャットを作った
Tetsuya Tatsumi
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門
Yusuke Wada
 
ぼくがかんがえたさいきょうのMvc
ぼくがかんがえたさいきょうのMvcぼくがかんがえたさいきょうのMvc
ぼくがかんがえたさいきょうのMvc
karupanerura
 
Gofのデザインパターン stateパターン編
Gofのデザインパターン stateパターン編Gofのデザインパターン stateパターン編
Gofのデザインパターン stateパターン編
Ayumu Itou
 
Perl logging
Perl loggingPerl logging
Perl logging
keroyonn
 

Viewers also liked (20)

Mojolicious::Liteを使ってみよう
Mojolicious::Liteを使ってみようMojolicious::Liteを使ってみよう
Mojolicious::Liteを使ってみよう
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてる
 
正月発火村に参加して変なJobQueueサーバー作った話
正月発火村に参加して変なJobQueueサーバー作った話正月発火村に参加して変なJobQueueサーバー作った話
正月発火村に参加して変なJobQueueサーバー作った話
 
Amon2 で造られた api サーバを引き継いで課金の実装をしました話
Amon2 で造られた api サーバを引き継いで課金の実装をしました話Amon2 で造られた api サーバを引き継いで課金の実装をしました話
Amon2 で造られた api サーバを引き継いで課金の実装をしました話
 
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
モダンでもなく reactでもなく フロントエンドでもなく 開発でもない話
 
Mojoliciousのログ出力を改造する in chiba.pm #3
Mojoliciousのログ出力を改造する in chiba.pm #3Mojoliciousのログ出力を改造する in chiba.pm #3
Mojoliciousのログ出力を改造する in chiba.pm #3
 
Mojolicious+redisでチャットを作った
Mojolicious+redisでチャットを作ったMojolicious+redisでチャットを作った
Mojolicious+redisでチャットを作った
 
PerlでWeb API入門
PerlでWeb API入門PerlでWeb API入門
PerlでWeb API入門
 
ぼくがかんがえたさいきょうのMvc
ぼくがかんがえたさいきょうのMvcぼくがかんがえたさいきょうのMvc
ぼくがかんがえたさいきょうのMvc
 
2013年のCPANモジュール作成事情
2013年のCPANモジュール作成事情2013年のCPANモジュール作成事情
2013年のCPANモジュール作成事情
 
Gofのデザインパターン stateパターン編
Gofのデザインパターン stateパターン編Gofのデザインパターン stateパターン編
Gofのデザインパターン stateパターン編
 
Technology for reduce of mistakes - うっかりをなくす技術
Technology for reduce of mistakes - うっかりをなくす技術Technology for reduce of mistakes - うっかりをなくす技術
Technology for reduce of mistakes - うっかりをなくす技術
 
First step of Performance Tuning
First step of Performance TuningFirst step of Performance Tuning
First step of Performance Tuning
 
CPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいCPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したい
 
2016年のPerl (Long version)
2016年のPerl (Long version)2016年のPerl (Long version)
2016年のPerl (Long version)
 
Json(::PP) is a-changing
Json(::PP) is a-changingJson(::PP) is a-changing
Json(::PP) is a-changing
 
Perl logging
Perl loggingPerl logging
Perl logging
 
データマイニング入門
データマイニング入門データマイニング入門
データマイニング入門
 
できる!サーバレスアーキテクチャ
できる!サーバレスアーキテクチャできる!サーバレスアーキテクチャ
できる!サーバレスアーキテクチャ
 
2017年春のPerl
2017年春のPerl2017年春のPerl
2017年春のPerl
 

Similar to Mojoliciousでつくる! Webアプリ入門

早稲田大学授業 - モバイルプログラミング
早稲田大学授業 - モバイルプログラミング早稲田大学授業 - モバイルプログラミング
早稲田大学授業 - モバイルプログラミング
Ippei Arita
 
Rubyで作るクローラー Ruby crawler
Rubyで作るクローラー Ruby crawlerRubyで作るクローラー Ruby crawler
Rubyで作るクローラー Ruby crawler
Takuro Sasaki
 
続・Twitter bootstrap入門 #html5j
続・Twitter bootstrap入門 #html5j続・Twitter bootstrap入門 #html5j
続・Twitter bootstrap入門 #html5j
Toshiaki Maki
 
「新しい」を生み出すためのWebアプリ開発とその周辺
「新しい」を生み出すためのWebアプリ開発とその周辺「新しい」を生み出すためのWebアプリ開発とその周辺
「新しい」を生み出すためのWebアプリ開発とその周辺
Yusuke Wada
 
Introduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature EngineersIntroduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature Engineers
Takeshi Arabiki
 

Similar to Mojoliciousでつくる! Webアプリ入門 (20)

Perl Beginners #7 おとなのWAF
Perl Beginners #7 おとなのWAF Perl Beginners #7 おとなのWAF
Perl Beginners #7 おとなのWAF
 
Single Command Deployのための gradle-aws-plugin講座
Single Command Deployのための gradle-aws-plugin講座Single Command Deployのための gradle-aws-plugin講座
Single Command Deployのための gradle-aws-plugin講座
 
Beginners scala 20121113
Beginners scala 20121113Beginners scala 20121113
Beginners scala 20121113
 
2015年GMOペパボ新卒エンジニア研修 Webオペレーション研修イントロダクション
2015年GMOペパボ新卒エンジニア研修 Webオペレーション研修イントロダクション2015年GMOペパボ新卒エンジニア研修 Webオペレーション研修イントロダクション
2015年GMOペパボ新卒エンジニア研修 Webオペレーション研修イントロダクション
 
【テックリンク】平日の夜1時間で学ぶ!RubyonRails初心者ハンズオン
【テックリンク】平日の夜1時間で学ぶ!RubyonRails初心者ハンズオン 【テックリンク】平日の夜1時間で学ぶ!RubyonRails初心者ハンズオン
【テックリンク】平日の夜1時間で学ぶ!RubyonRails初心者ハンズオン
 
【Camphor ×サイボウズ】selenium勉強会
【Camphor ×サイボウズ】selenium勉強会【Camphor ×サイボウズ】selenium勉強会
【Camphor ×サイボウズ】selenium勉強会
 
Rails解説セミナー: Rails国際化 (I18n) API
Rails解説セミナー: Rails国際化 (I18n) APIRails解説セミナー: Rails国際化 (I18n) API
Rails解説セミナー: Rails国際化 (I18n) API
 
遅いクエリと向き合う仕組み #CybozuMeetup
遅いクエリと向き合う仕組み #CybozuMeetup遅いクエリと向き合う仕組み #CybozuMeetup
遅いクエリと向き合う仕組み #CybozuMeetup
 
早稲田大学授業 - モバイルプログラミング
早稲田大学授業 - モバイルプログラミング早稲田大学授業 - モバイルプログラミング
早稲田大学授業 - モバイルプログラミング
 
Djangoのススメ
DjangoのススメDjangoのススメ
Djangoのススメ
 
Rubyで作るクローラー Ruby crawler
Rubyで作るクローラー Ruby crawlerRubyで作るクローラー Ruby crawler
Rubyで作るクローラー Ruby crawler
 
続・Twitter bootstrap入門 #html5j
続・Twitter bootstrap入門 #html5j続・Twitter bootstrap入門 #html5j
続・Twitter bootstrap入門 #html5j
 
Hatena blogdevelopmentflow
Hatena blogdevelopmentflowHatena blogdevelopmentflow
Hatena blogdevelopmentflow
 
「新しい」を生み出すためのWebアプリ開発とその周辺
「新しい」を生み出すためのWebアプリ開発とその周辺「新しい」を生み出すためのWebアプリ開発とその周辺
「新しい」を生み出すためのWebアプリ開発とその周辺
 
Tech fun rails_workshop
Tech fun rails_workshopTech fun rails_workshop
Tech fun rails_workshop
 
「Webサービスのつくり方」 のつくり方
「Webサービスのつくり方」 のつくり方「Webサービスのつくり方」 のつくり方
「Webサービスのつくり方」 のつくり方
 
Electron early 2019
Electron early 2019Electron early 2019
Electron early 2019
 
Introduction of Rhodes
Introduction of RhodesIntroduction of Rhodes
Introduction of Rhodes
 
Introduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature EngineersIntroduction to Favmemo for Immature Engineers
Introduction to Favmemo for Immature Engineers
 
20140523 jQuery基礎 (HTML5ビギナーズ)
20140523 jQuery基礎 (HTML5ビギナーズ)20140523 jQuery基礎 (HTML5ビギナーズ)
20140523 jQuery基礎 (HTML5ビギナーズ)
 

More from Yusuke Wada

僕らがWebサービスをつくる5つの理由
僕らがWebサービスをつくる5つの理由僕らがWebサービスをつくる5つの理由
僕らがWebサービスをつくる5つの理由
Yusuke Wada
 

More from Yusuke Wada (20)

僕がつくった 70個のうちの48個のWebサービス達
僕がつくった 70個のうちの48個のWebサービス達僕がつくった 70個のうちの48個のWebサービス達
僕がつくった 70個のうちの48個のWebサービス達
 
スッとGoを取り入れる
スッとGoを取り入れるスッとGoを取り入れる
スッとGoを取り入れる
 
東京脱出計画中
東京脱出計画中東京脱出計画中
東京脱出計画中
 
Extreme remote working
Extreme remote workingExtreme remote working
Extreme remote working
 
Podcastを支える技術、エンジニアのためのWebメディア、そしてCPAN
Podcastを支える技術、エンジニアのためのWebメディア、そしてCPANPodcastを支える技術、エンジニアのためのWebメディア、そしてCPAN
Podcastを支える技術、エンジニアのためのWebメディア、そしてCPAN
 
創造のプロセスを回せ!v0.01
創造のプロセスを回せ!v0.01創造のプロセスを回せ!v0.01
創造のプロセスを回せ!v0.01
 
It's not only about "REMOTE"
It's not only about "REMOTE"It's not only about "REMOTE"
It's not only about "REMOTE"
 
事故からはじまるスケールチャンス
事故からはじまるスケールチャンス事故からはじまるスケールチャンス
事故からはじまるスケールチャンス
 
Google BigQueryを使ってみた!
Google BigQueryを使ってみた!Google BigQueryを使ってみた!
Google BigQueryを使ってみた!
 
Webサービスのコンテンツパターン 或いはデータの活⽤
Webサービスのコンテンツパターン 或いはデータの活⽤Webサービスのコンテンツパターン 或いはデータの活⽤
Webサービスのコンテンツパターン 或いはデータの活⽤
 
とある Perl Monger の働き方
とある Perl Monger の働き方とある Perl Monger の働き方
とある Perl Monger の働き方
 
5 minutes - YAPC::Asia Tokyo 2014
5 minutes - YAPC::Asia Tokyo 20145 minutes - YAPC::Asia Tokyo 2014
5 minutes - YAPC::Asia Tokyo 2014
 
Podcastをカジュアルに 支える技術
Podcastをカジュアルに 支える技術Podcastをカジュアルに 支える技術
Podcastをカジュアルに 支える技術
 
The master plan of scaling a web application
The master plan ofscaling a web applicationThe master plan ofscaling a web application
The master plan of scaling a web application
 
そのWebサービスは本当に「あたりまえ」だったのか?
そのWebサービスは本当に「あたりまえ」だったのか?そのWebサービスは本当に「あたりまえ」だったのか?
そのWebサービスは本当に「あたりまえ」だったのか?
 
10 things to learn from Bokete
10 things to learn from Bokete10 things to learn from Bokete
10 things to learn from Bokete
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
僕らの履歴書
僕らの履歴書僕らの履歴書
僕らの履歴書
 
僕らがWebサービスをつくる5つの理由
僕らがWebサービスをつくる5つの理由僕らがWebサービスをつくる5つの理由
僕らがWebサービスをつくる5つの理由
 
僕らがつくるための 「5W」について
僕らがつくるための 「5W」について僕らがつくるための 「5W」について
僕らがつくるための 「5W」について
 

Recently uploaded

Recently uploaded (11)

Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 

Mojoliciousでつくる! Webアプリ入門