読者です 読者をやめる 読者になる 読者になる

ゆーすけべー日記

はてなBlogってどーなの!?

Webサービスを支える「Perlモジュール」20選

この記事はPerl 5 Advent Calendar 2015の一貫として「先走って」書いております。

ただいま、絶賛「IVS CTO Night&Day 2015 Fall」というイベントに来ていて100名ほどのスタートアップやベンチャーのCTOさん達に囲まれています。そのイベントの事前のアンケートには「社内での主力言語はなんですか?」みたいな質問がありました。さて結果発表を画像で貼り付けますと...

f:id:kamawada:20151207200903j:plain

ちょっと見えにくいかもしれませんが「Rubyが27 PHPが20」を占める中「Perlが1」という結果です。僕Perlって書いたので「Perl主力なところってうちだけ」ですねw

まぁといってもちょっとそれは過小評価な表現で、はてなさんがScalaとPerlをどちらも主力と考えていたり「アンケートに答えなかった」というガイアックスさんもPerl企業です。このイベントに参加していない企業さんでも、Perlを使っている実力のある社名がぱっと浮かびます。ただ!そもそもアンケートの選択肢にPerlがなかったので「その他自由欄」に記載しなくてはいけなかったり、写真にある通りスライド上に「Perl 1」とあるのはちょっと寂しいのです...

前置きが長くなってきましたが「Perlぜんぜんイケてるやん」って思うし、アンケートに回答した通りBoketeのバックエンド及びフロントのWebサイトはほぼ100%Perlで書かれています。Perlが担当するアプリケーションレイヤーはすごく安定稼働です。ってことでPerlでWebサービスをつくる際に必須なCPANモジュールの中から、主にBoketeで使っているものを20個ほどピックアップしてみます。元々Perlを使っている方にとっては当たり前なモジュールかもしれませんが他言語を使ってる方が「Perlもライブラリ揃ってるやん」って思ってくれるとこれ幸いです。

ではいってみましょー

基本モジュール

1. Mouse

Perlでも素でOOPは出来るのですが、具体的なアプリケーションレベルだとこのMouseを使ってクラスをつくってます。継承、Roleの概念もあります。面白い機能の一つにlazy_buildがあります。これはアクセッサを定義する際にlazy_buildを指定すると「初めて呼ばれた際に」デフォルトの値をセットしてくれるというものです。

use Mouse;
use LWP::UserAgent;

has ua => ( is => 'ro', isa => 'LWP::UserAgent', lazy_build => 1 );

sub _build_ua {
    return LWP::UserAgent->new();
}

sub get_content {
    my ($self, $args) = @_;
    my $url = $args->{url};
    my $res = $self->ua->get($url);
    return $res->content;
}

Mouseの他にも元ネタだったり派生したものとしてMooseやMooもありますので、これらを使えばOOPは快適です。

2. Data::Validator

メソッドの引数の型を含む「チェック」に使っています。上記のコード例にあるget_contentをより厳密にしたい!なんて時はこんな感じで使います。

use Data::Validator;
...;

sub get_content {
    state $rule = Data::Validator->new(
        url => {
            isa => 'Str',
            default => 'http://yusuke.be/',
            optional => 0
        }
    )->with('Method');
    my ($self, $args) = $rule->validate(@_);
    my $url = $args->{url};
    my $res = $self->ua->get($url);
    return $res->content;
}

3. Try::Tiny

モダーンにエラーハンドリングを書けます。

try {
    die "dying message...";
} catch {
    warn "Error: $_";
};

4. Path::Tiny

モダーンにローカルファイルのパス解決をしてくれます。それに加えて、ファイルの内容を舐めるslurpや書き出すためのspewなどもあります。

use Path::Tiny;

my $file = path('foo.txt');
my $text = $file->slurp();
print $text;

Webのバックエンド

5. Mojolicious

Perlにももちろん様々なWebフレームワークがありますが、サクッとつくったりある程度の規模かつViewまで担当するって時にはこのMojoliciousを僕は使ってます。 Perlには珍しくアグレッシブに後方互換を切り捨てるという開発方針があったりするのですが、まぁそれは置いといて、このフレームワークはRubyで言うSinatraとRailsの中間みたいな感じですごく使いやすいです。

6. Plack

フレームワークを使う分には触ることはないのですが、より特化したケースやパフォーマンスを重視したい際にはPSGIの実装であるPlackを素で使います。RubyにおけるRackの立ち位置なのですが、Perlの場合だとこれから紹介するいくつかのモジュールと組み合わせることによって実用的なアプリをつくりやすいです。

7. Router::Boom

例えばですが「このパスにアクセスが来たらこうする」というディスパッチャとしてRooter::BoomをPlackなどと組み合わせています。パス/entry/100に来たリクエストをコントローラEntryshowというメソッドで処理するなんて場合はこんなコードで再現出来ます。

use Router::Boom;

my $router = Router::Boom->new();
$router->add(
    '/entry/{entry_id:[0-9]+}',
    { controller => 'Entry', method => 'show' }
);
my $dest = $router->match('/entry/100');
# => {controller => 'Entry', method => 'show', entry_id => '100' }

8. JSON::RPC

BoketeではWeb APIのフォーマットとしてJSONRPCを採用しているので使っています。アプリ内では継承して若干改造しているのですが、まぁ問題なしで使えております。

9. OAuth::Lite2

これもBoketeアプリの認証認可という点でサーバ側及びクライアント側でも利用させてもらってます。他にもOAuthの実装はあるのですが、作者が日本人の方でよく熟考して実装されている、かつ、実装もシンプルなのでオススメです。というか今回紹介しているモジュールの多くは日本人の方がメンテしてくれているので「困った時に聴ける」「開発意図が分かる」ので良いです。

10. Starlet

PSGI対応のハイパフォーマンスWebアプリケーションサーバーです。なので上記したMojoliciousやPlackで実装したアプリケーションを本番環境で動かす際に必要となります。他にも、Starman、GazelleなどPSGIに対応したサーバーソフトがあるので用途に応じて使わけるといいでしょう。Server::StarterとあわせるといわゆるGraceful Restartも出来るし、運用上Appサーバーレベルで異常が起きたことがほぼ無いので安心感あります。

Webアプリに便利

11. FormValidator::Lite

Webフォームの値を検証することに特化したライブラリです。なのでバリデーションをコントローラ層でもモデルでもどこでも自分が好きなところでやっちゃっうことが出来るでしょう。ベーシックにコントローラ部分でやる例としてMojoliciousをつかった例はこのようになります。

use Mojolicious::Lite;
use FormValidator::Lite;
FormValidator::Lite->load_constraints(qw/Japanese/);

post '/' => {
    my $c = shift;
    my $validator = FormValidator::Lite->new($c->req);
    my $res = $validator->check(
        name => [qw/NOT_NULL/],
        name_kana => [qw/NOT_NULL KATAKANA/],
        {mails => [qw/mail1 mail2/]} => ['DUPLICATION'],
    );
    if ($validator->has_error) {
        return $c->render( text => 'Not valid!' );
    }
    $c->render( text => 'Valid!' );
};

app->start;

12. HTML::FillInForm::Lite

テンプレートなどを使って描画するHTMフォームの個々の要素のそれぞれに値を充填することが出来ます。ようは「戻るボタン押したら入力したのが全部消えてる><」問題が解決出来ます。

13. HTML::Scrubber

MojoliciousのテンプレートMojo::Templateをはじめ、テンプレートエンジンには大抵HTMLエスケープ処理を容易にする、もしくは、デフォルトでエスケープされる機能がついています。が、場合によっては生HTMLをデータで持っていて、scriptタグ等除去してそのまま描画したい、なんてことがあります。その際にこのHTML::ScrubberでタグをWhite or Black List形式で指定してセーフティにしています。

DB操作

14. Teng

ガッツリしたO/R MapperもあるんですがTengは厳密にはO/R Mapperとも言えないんじゃないか!ってほど簡素なDB操作をするためのモジュール。なので勝手にJOINが走るなんてことがないです。インターフェースもシンプルで直感的なのが好きですね。

my $iter = $db->search(
    'entry',
    { category => 'podcast' },
    { order_by => { id => 'desc' } }
);
while(my $entry = $iter->next) {
    say $entry->title();
}

15. SQL::Maker

Tengは生SQLも受け付けるので、複雑なクエリを発行したい場合や条件で分岐したい時などはこのSQL::MakerでクエリをつくってからTengに渡すなんてことをしています。ようはこれ書きやすいクエリビルダーです。実はTengの内部でも利用されています。

その他

16. Imager

画像を扱う場合はGDやImageMagickのラッパーが存在するのでそれを叩けばいいのですが、このImagerの方がAPIがPerlishで使用感が良いです。

デバグとテスト

17. Devel::KYTProf

データベースやmemcachdへのクエリやHTTPのリクエスト状況などを開発しながら見ていくことは非常に重要です。その際にコード内で use Devel::KYTProfするだけで標準出力に

0.228 ms  [Cache::Memcached::Fast]  get dbs:54e98de3b9aed9064e1834e0d6ac3a636a981f9f  | Bokete::DB::Row::Boke:48

とかでちゃうの素敵です。

18. Test::mysqld

MySQLをバックエンドに持つアプリケーションをテストする際に便利すぎる。テストを走らせている間だけテンポラリーなmysqldが立ち上がります。

19. Harriet

大抵proveというコマンドで複数ファイルにわかれたテストをまとめて実行するのですが、Test::mysqldをprove中に使いまわしたりってのに使ってます。BoketeではMySQLだけではなく、MemcachedとRedisをテストの際、こいつで立ち上げてたりします。

20. Test::JSON::RPC::Autodoc

手前味噌で恐縮ですが、JSONRPCを喋るPlackアプリケーションに対してテストを簡便に記載できるだけじゃなくて、APIドキュメントもMarkdown形式で書きだしてくれるモジュールです。Ruby実装のautodocをモチベーションにしてつくりました。Boketeではこれを使って吐き出したMarkdownをGitHub上で見てもらうことで仕様の共有をしています。

まとめ

以上、実践で使用しているモジュール群から「特徴的で」かつ「これがなきゃ困るぜ!」というライブラリを20個紹介しました。Perlはグルー言語とも呼ばれこうしたCPANモジュールを組み合わせて自分達なりにアプリケーションをつくっていけるので、非常に楽しい側面があります。それぞれドキュメントへのリンクを張っているので興味があれば見てみて下され!


Perlはじめる時にオススメの2冊

初めてのPerl 第6版

初めてのPerl 第6版

続・初めてのPerl 改訂第2版

続・初めてのPerl 改訂第2版