八発白中

はてなブログに引越しました。

Day 5: ningle

これは fukamachi products advent calendar 2016 の5日目の記事です。

今日はningleについて話します。

Cavemanをもっと小さく

CavemanはマイクロWebフレームワークではありましたが、一般的なものと違ってプロジェクト雛形生成機能がついていました。

PerlのAmon2から影響されて作られたので当然と言えば当然なのですが、RubySinatraPythonのFlaskのようにまずは1ファイルでさらっと書いて起動できるといった手軽さに比べると鈍臭く感じてしまいます。

これはCavemanが悪いわけではありません。他のフレームワークがURLディスパッチャしか提供していないのに対し、Cavemanはテンプレートエンジンとの連携や環境による設定の切り替えなども含まれ、プロジェクトのディレクトリ構造がある程度固定されるのです。

けれども仮に、そこを敢えて1ファイルだけで完結できるようなフレームワークにするならどのようなものだろうと思いつき、それを作ってみることにしました。

そのフレームワークが「ningle」です。

名前の由来はアイヌ伝承の小人「ニングル」です。Cavemanが無骨な原始人とすれば、ningleは可愛げのある小人だというわけです。

アノテーションではなくsetf

3日目のCavemanの記事で、アノテーションによるルーティングルール定義について話しました。一方でningleはsetfを使った定義をします。

(defvar *app* (make-instance 'ningle:<app>))

(setf (ningle:route *app* "/")
      "Welcome to ningle!")

(setf (ningle:route *app* "/login" :method :POST)
      #'(lambda (params)
          (if (authorize (cdr (assoc "username" params :test #'string=))
                         (cdr (assoc "password" params :test #'string=)))
              "Authorized!"
              "Failed...Try again.")))

(clack:clackup *app*)

Common Lispsetfは代入の意味ではありますが、その動作は自分で定義することができます。setf ningle:routeはappのルーティングルールに追加するという挙動です。

なぜ今回はアノテーションを使わなかったのか。それはningleが小さいだけでなく単純でなければならないという設計思想が所以でした。

新しいアノテーションやマクロはユーザーに使い方を覚えてもらう必要があります。一方でsetfはCommon Lispの標準の機能であり、親しみやすく、学習コストも下がります。

Lispのマクロは強力です。マクロがあるからLispを使うといっても過言ではありません。けれど、それはむやみに使えばいいというものではありません。学習コストと天秤にかけて、利便性が勝るときだけ使うから光るのです。

さらにningleでは、Clackにある機能は隠蔽せずにそのまま使うことにしました。このためningleではClackの使い方を知っていることを前提としてはいますが、その分Clackに親しんだ人には扱いやすく感じると思います。

これらの違いがningleを機能の少ないCavemanではなく、シンプルで取り回しの効くマイクロWebフレームワークにしたと自負していたのですが、誤算もありました。

Caveman vs ningle

ningleをリリースしてからとても多くの人にGitHubやメールなどで同じ質問を受けました。

「Cavemanとningleの2つあるようだけど、違いは何?どちらもマイクロWebフレームワークと書いてある。どちらを使うべきだろう?」

好きな方を使えばいいだけなのですが、選択肢が多いと不安になる気持ちもわかります。

同じ質問に答えるのに飽き飽きしていた僕は、そこでCavemanをより進化させ、完全にningleとの差別化を図りました。そういった経緯で作られたCaveman2はRDBMSとの連携が標準対応しており、一般的なWebアプリケーションで必要な最小限のものは揃えてあります。

また、Caveman2はなんとningleに依存しています。内部のURLディスパッチャ部分をningleを使うことで、階層的なプロダクトであることが明示できるとともに、Clackの思想である再利用性を実現しています。まあ、似たコードを2つメンテしたくないっていうのもあったんですけど。

それからのWebアプリケーションはCaveman2で作るほうが一般的になり、ningleはアプリケーション内に埋め込むような小さなHTTPアプリケーションとしての用途で使われることが多くなりました *1

おわりに

ningleはGitHubで公開されており、現在Starは110です。

明日のアドベントカレンダーは6日目のcircular-streamsについてです。お楽しみに。

*1:たとえばQlotのQuicklisp dist配布用のモックサーバーなど