Clojure Web Development勉強 - Ring (その1)
Clojureで囲碁対局サイトを作ってみたい - Arantium Maestum
でも書いた通り、中規模ウェブアプリ的なものを開発してみたい。そのためのライブラリについて、色々と覚書をメモっておく。
Clojureでウェブ開発する場合、サーバサイドの根幹はほぼ必ずringというライブラリを使うようだ。
HTTPサーバとのリクエスト・レスポンスのやり取りを担当するライブラリである。
サーバからのリクエストをClojureお馴染みのimmutableなmapデータに変換し、そしてサーバ側に投げ返すレスポンスもまたimmutableなmapから自動的に作成してくれる。そうすると、開発者側ではリクエスト情報が含まれるデータ構造を受け取り、レスポンス情報が含まれるデータ構造を返す純粋関数を作成することに注力するのみとなり、関数型プログラミング好きとしてはなかなか嬉しいことになる。あと、各種サーバのAPIの違いなどをringが吸収してくれるというメリットも大きい(ようだ)。
いつもながらathosさんのご教示に感謝。
@zehnpaard RingというのはHTTPリクエストをマップでもらってレスポンスをマップで返せばOKという仕組みを作っている部分で、Compojureは基本的にはどのエンドポイントへのリクエストでどの処理を実行するかを決定するルーティングを担います。
— えいとす)))))))) (@athos0220) 2016年10月25日
大抵はcompojureやbidiといったルーティングライブラリと合わせて使うことがほとんどらしい。compojureあたりは結構ringの実装を隠蔽してより高次なレベルで書けるようにしてくれる部分もあるみたい。今はとりあえずring自体と慣れ親しみたいのでcompojureは使わないでおく。
まあかなり最低限なプロジェクトとして、どんなリクエストにも同じ文字列を返すハンドラと、そのハンドラを包む形でリクエストとレスポンスをatomにログする高階関数、サーバとしてJetty、そしてそれらをreplで走らせられるような簡単な枠組みを作ってみた。
ちなみにこのloggerがいわゆるmiddlewareというパターンで、高階関数としてハンドラに機能を追加していく。ringライブラリ自体にも便利なmiddlewareがいろいろあるみたいなので調べていきたい。
ともかく、このコードをreplで走らせればサーバがreplをブロックすることなく立ち上がるので、ブラウザでlocalhost:8080/開けば確認できる。
コード変更があったらとりあえず全部Evalしてウェブページをリロードすれば反映されるし、replで@log-atomを参照することで時系列順にリクエストとそれに対するレスポンスがベクタに入っているのを直接見ることができる。というか、ページロードごとにリクエストが二つ(ページとfavicon.ico分)送られてるの、初めて知った・・・
これでとりあえずいろいろいじりながらrequest/responseともに触って確認できる環境が整った。middlewareを含むringの機能をさらに使い倒してみようと思う。
追記:当然ながら、gistに乗っけたコードは自分の開発・勉強のために役に立つlogger機能であって、本番環境で使うとメモリリークするのでやめましょう、ととりあえず無意味な保身をしておく。