Crystalでこんな感じにWebアプリを書けたらきっと幸せだろうなという妄想

  • 7
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

この記事はCrystal Advent Calendarの18日目の記事です。

CrystalのWeb Application Frameworkをあさっていて、好きなフレームワークが見つからなかったので、
こういうのが欲しいな。書きたいな。あるいはだれか書いてほしいなって感じのやつです。
名前はとりあえずWavesとしていますが変えるかも。

require 'waves'

class MyApp::Middleware::Sample
  include Waves::Middleware

  on_req do |c|
    # you can hook on request (e.g. authorization
  end

  on_res do |c|
    # you can hook on request
  end
end

class MyApp::Context
  include Waves::Context

  BASE_DIR = "./template"

  view(:json) do |c|
    Waves::View::JSON.new
  end

  view(:html) do |c|
    Waves::View::ECR.new(c, BASE_DIR)
  end
end

class MyApp::Controller::Root
  include Waves::Controller

  def index(c) # c is context object
    foo = c.req.parameters["foo"] # => Str|Array(Str)
    c.view(:html).render("path/to/index.ecr", { :foo => foo }) do |res|
      res.cookies.set("foo", "bar", { :secure => true }) # optional
      res.headers["X-MyApp-Header"] = "Hoge" # optional
    end
  end
end

class MyApp::Router
  include Waves::Router

  get "/", MyApp::Controller::Root, :index
end

class MyApp::Server
  include Waves::Server

  context MyApp::Context
  router MyApp::Router

  middlewares do
    enable MyApp::Middleware::Sample
  end
end

MyApp::Server.new(8080).run()

疎結合なパーツを作って関連付けることで大きなものを作るという感じが好きなのです。

View

レスポンスとして返すデータを整形するやつです。
デフォルトでよくあるやつは定義されますが独自のものを使うこともできます。

Middleware

リクエストやレスポンスにフックする君です。

Cotnext

ユーザーからのリクエストごとに生成されるコンテキストです。
コンテキストがRequest/Responseなど、リクエストのコンテキストを表現するオブジェクトを持ちます。
また、コンテキストに依存する各機能への移譲も行います。
PerlのAmon2が分かる人向けに言えばAmon2::Webに近いといえます。

Controller

エンドポイントで行われる処理を定義します。
Contextオブジェクトが渡されます。
こんな具合でContextとおなじインターフェースを作ればmockできるようにしてテストしやすくしたいです。

Router

ルーティングを定義します。
get とかをmacroとして提供してコンパイル時にルーティングテーブルが構築されて楽しい感じにしたいです。

Server

アプリケーションを構成する要素を結合してWebサーバーをコンパイル時に実装します。
コンパイル時に実装できると楽しい。

課題

マクロ芸の能力がまだたりない

まとめ

こんな感じの疎結合でテストしやすいWAFができて、かつMySQLがCrystalから使えるようになって、かつPerl5のDBIみたいなやつが提供されると、個人的にはCrystalでWebアプリ書くのだいぶ良い選択肢になるので、
そういう世界にしたいし、ぼくはそこを目指したいなという気持ちでいっぱいです。
まだまだyak shavingがたくさんひつようそうで道のりが長そうですが、のんびり頑張っていきたい。