PlackコードリーディングでWebアプリケーションの仕組みを理解する

この記事はPerl Advent Calendar 2017の19日目の記事です。昨日、18日は[@take_3さん](https://qiita.com/take_3)による「[VSCodeでPerlデバッグ](https://qiita.com/take_3/items/e889be9878e8516c89a3)」でした。VSCode、ずっと興味が有るんですが、なかなか使ってないので、そろそろ使ってみようかと思いました。

本日19日目は、[吉祥寺.pm](https://kichijojipm.connpass.com)というPerlの(?)イベントを定期的に開催しています[Magnolia.K](https://twitter.com/magnolia_k_)がお送りします。

今日のネタは本当は22日に予定していたものだったのですが、19日用のネタがなかなか書き進まなかったので、今日公開します。

題して、「PlackコードリーディングでWebアプリケーションの仕組みを理解する」です。

---

## Webアプリケーションの仕組みを理解する

最近、自分のOSS活動としてPerlを書く機会はかなり減ってしまい、もっぱら[Scalatra](http://scalatra.org)というScala用のWeb Application Frameworkのサンプルコードやドキュメントなどを直していることが多いです。

しかし、元々日常的にWebアプリケーションを書いている、という訳では無いので、Webアプリケーションの構造について忘れてしまったり、元々仕組みを理解していない箇所に遭遇することが有り、改めてアプリケーションサーバや、フレームワークなども含めたWebアプリケーションの構造を理解しないといけないな、と考えました。

[Scalatra](http://scalatra.org)はJavaでお馴染みの[Servlet](https://ja.wikipedia.org/wiki/Java_Servlet)という仕組みの上で動作するフレームワークですが、Servlet対応のアプリケーションサーバと言えば[Jetty](https://www.eclipse.org/jetty/)や、[Tomcat](http://tomcat.apache.org)といった巨大な実装ばかりで、ここを出発点として理解するのは骨が折れそうだ、と思いました。

そこで少し遠回りにはなりますが、まずはPerl MongerとしてPlackとそこで使われているモジュール周りのコードをじっくり読むことで理解を進めることにしました。

## HTTP実装リファレンスとしてのPlackの活用

そもそもPlackって何？という方は以下の記事をまずはお勧めします。

[第1回　PSGI/Plack―フレームワークとサーバをつなぐエンジン （1）：Perl Hackers Hub](http://gihyo.jp/dev/serial/01/perl-hackers-hub/000101)

また、ソースコードはGitHub上にあります。

[https://github.com/plack/Plack](https://github.com/plack/Plack)

Plackのコードリーディングを通じてWebアプリケーションの構造を理解することは以下の利点が有ると思っています。

なぜPlack(というか、Perl)に戻ったか?その理由は以下の通りです。

### Perlのモジュールは粒度が小さい

 Plack自体にも一定のコードが含まれていますが、それ以上にさまざまな既存のモジュール(コアモジュール、CPANモジュール)を利用しています。これらPerlのモジュールの傾向として、1つ1つのモジュールが粒度が小さく独立していて、機能ごとに分けて理解し易いということが挙げられます。また、モジュールの命名規約がネームスペースを区切って、一般名詞の組み合わせになっているので、モジュール名から機能を推測し易くなっています。

　例えば、Plackのcpanfile(Perlの依存モジュールを定義する設定ファイル)に書かれている`HTTP::Headers::Fast`、`HTTP::Message`といったモジュール名からなんとなく機能が推測できると思いませんか？(それぞれ、HTTPプロトコルのヘッダの読み書きをするモジュールと、HTTPプロトコルのメッセージ全体を保持するモジュールです)

　`Cookie::Baker`もギリ分かりますね(当然、Cookieを読み書きするためのモジュールです)。

### モジュールごとにドキュメントが整備されている

巨大なアプリケーションの内部実装であれば、外部ドキュメントがきちんと整備されていることはあまり無いと思いますが、先ほど説明したようにPerlのモジュールの粒度は小さく、内部実装用のモジュールでも独立したディストリビューションとして整備されているので、それぞれに詳細なドキュメントが用意されています。

例えば先ほどの`Cookie::Baker`のドキュメントは当然のようにCPANで読むことができます。

[https://metacpan.org/pod/Cookie::Baker](https://metacpan.org/pod/Cookie::Baker)

更にモジュールが既にインストール済であれば`perldoc Cookie::Baker`でオフラインでもすぐに読めるところがPerlの良いところですね。

### 速度が要求されるモジュールにはPure Perl版と、XSモジュール(C言語)が用意されている

特に速度が要求されるモジュールにはPure Perl版に加えてXS版(C言語)の2種類が用意されていて、一度に2つの実装を追いかけることができる

例えば`Cookie::Baker`には、XS版の`Cookie::Baker::XS`が用意されています。つまり、Perlに加えてC言語での実装についても同時に理解することができ、お得です!!

他にも`JSON`と`JSON::PP`、`[HTTP::Parser::XS](http://search.cpan.org/~kazuho/HTTP-Parser-XS-0.17/lib/HTTP/Parser/XS.pm)`と`HTTP::Parser::XS::PP`あたりはお勧めです。

### プロダクションレベルで使われてきた実績のある実装

最近でこそ新規のプロジェクトでPerlを採用する事例を聞くことが少なくなってきましたが、PlackベースのWebアプリケーションは数々の大規模ウェブサービスで使われてきた、実績のあるものです。

サンプル実装ではなく、実際に動いて、価値を提供してきたコードを好きなだけ読めるので、非常に参考になります。

また、それぞのモジュールは名前を挙げればキリが無いほどの歴戦のPerl Monger達の、シンプルで読みやすいコードが詰まっているので、コードの書き方として非常に勉強になります（どのモジュールも意外なくらい短いです！)

## コードリーディングのスタート地点

さて、では実際にどこから読み進めるのが良いか？

Plackに付属する[HTTP::Server::PSGI](https://github.com/plack/Plack/blob/master/lib/HTTP/Server/PSGI.pm)というシンプルなアプリケーションサーバや、[HTTP::Request](https://github.com/plack/Plack/blob/master/lib/Plack/Request.pm)、[HTTP::Response](https://github.com/plack/Plack/blob/master/lib/Plack/Response.pm)あたりが良いでしょう。

Plack本体ではありませんが、一定規模のWebアプリケーションでは必須の[Plack::Middleware::Session](http://search.cpan.org/dist/Plack-Middleware-Session/)や、Webアプリケーションフレームワークである[Kossy](https://metacpan.org/pod/Kossy)も参考になります(重ねて言いますが、どれもコード量は決して多くはないですし、ドキュメントがしっかり用意されています)。

## おわりに

一回遠回りしてPlackのコードをじっくり読んだおかげで、Servlet固有の機能は別として、Webアプリケーションとして、どんな機能が求められるのか？という所が概ね理解できたので、ScalaのWebアプリケーションフレームワークへのコントリビュートする上でも非常に役に立ちました！

やっぱりPerlの豊富な資産は最高ですね！

明日20日は、[cat2kobanさん](https://qiita.com/cat2koban)です。お楽しみに！