八発白中

技術ブログ、改め雑記

Common Lispの軽量フレームワーク「ningle」を作りました

Clackベースの軽量Webフレームワーク「ningle」を作りました。

背景

Clackベースのフレームワークとしては既に「Caveman」がありますが、CavemanはPerlのAmon2に影響を受けたこともあり、プロジェクトの拡大に伴う拡張性を損なわないために多くのことをします。

たとえばCavemanにはprojectという概念があり、開発環境と本番環境でロードするconfigファイルを分けたり、どのようにビルドするかを定義したりできるようになっています。

複数のClackアプリを定義することもでき、最初はPCサイトのみ作っていたけど半年後にスマートフォン用サイトも作ることになった、という場合などにも、アプリの継承などですぐに対応できるようになっています。

Clackのミドルウェア利用も記述を少し追加するだけです。

けれど、これらの拡張性のために、最初にプロジェクトのスケルトンを生成する必要があります。これでは試しながらちょっとずつ作っていきたいという気軽さが欠けます。

ningleは、プロジェクトのスケルトン生成をすることなくWebアプリを書くことができる、Cavemanよりさらに薄いWebアプリケーションフレームワークです。

特徴

  • ルーティング以外余計なことしない
    • リクエストとレスポンスをパースしてディスパッチするくらい
  • Clackを生で使いたいときも楽
    • 逆に言えばCavemanほど綺麗にClackをラップしていないのでClack慣れしてないと難しい
  • 妙なマクロ使わないからわかりやすい
    • cl-annot嫌いな方も安心

使い方

git cloneしてロードしたあと以下のような感じで書けば http://localhost:5000/ で起動します。

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

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

(setf (ningle:route *app* "/login" :method :POST)
      #'(lambda (params)
          (if (authorize (getf params :|username|)
                         (getf params :|password|))
            "Authorized!"
            "Failed...Try again.")))

(clack:clackup *app*)

Cavemanでは @url アノテーションのために多少トリッキーなことをしていて、アプリケーションを意識しなくても使えるようになっていますが、ningleでは見ての通り *app* がむき出しです。

ルーティング記述も、他のフレームワークと違って、アノテーションdefine-route のようなマクロではなく、単なる setf を使っています。マクロを使わずに最も自然に書くにはどうすればいいかと考えた末にこの形になりました。とても気に入っています。

最後には、単純にclackupするだけです。*app*に直接アクセスできるので、ここでClack.Builderを使ってClackミドルウェアを有効にすることもできます。

(import 'clack.builder:builder
        'clack.middleware.session:<clack-middleware-session>)

;; セッション機構を有効に
(clack:clackup
  (builder
    <clack-middleware-session>
    *app*))

どう?

Quicklisp

申請中です。 4月のupdateで取り込まれました。(ql:quickload :ningle)でインストールできます。

まとめ

まだ実験段階ではありますが、ベースはClackですし、Cavemanからの流用も多いので十分実用的な品質かと思います。興味がある方はぜひ触ってみてください。