先日開催された Railsdm はチケットが即完売してしまって残念ながら行けませんでした。
何か試してブログに書けそうなネタはないかなーとセッションの資料を見ていたら Roda という Web Framework が紹介されていました。
セッションでは Rails と組み合わせて使ってみるという内容でしたが、シンプルに Roda を動かしてみるサンプルはあまり多くなかったようなので、試してみました。
Roda とは
詳しくは本家サイトや上記 Railsdm のセッション資料等をご覧いただければと思いますが、 Rails のようなフルスタックのフレームワークとは違い、ルーティング機能を提供するシンプルなフレームワークで、 Sinatra に近いイメージです。様々なプラグインが用意されていますので、必要に応じてプラグインを追加して機能追加していく形になります。ルーティングをツリー構造で定義できる点が Sinatra と違う点になります。
Roda のインストール
Roda の GitHub リポジトリはこちらで、 gem のインストール方法やシンプルなアプリケーションのサンプルが紹介されています。
Roda のインストールは gem をインストールするだけです。今回は Bundler を使ってインストールしてみますので、下記のように Gemfile を用意します。
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "roda"
そして bundle install
します。
$ bundle install Fetching gem metadata from https://rubygems.org/............... Resolving dependencies... Using bundler 1.17.2 Using rack 2.0.6 Fetching roda 3.18.0 Installing roda 3.18.0 Bundle complete! 1 Gemfile dependency, 3 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
サンプルアプリケーション
とりあえず GitHub で紹介されているサンプルアプリケーションを実装してみます。下記の内容で config.ru ファイルを用意します。
require "roda" class App < Roda route do |r| # GET / request r.root do r.redirect "/hello" end # /hello branch r.on "hello" do # Set variable for all routes in /hello branch @greeting = 'Hello' # GET /hello/world request r.get "world" do "#{@greeting} world!" end # /hello request r.is do # GET /hello request r.get do "#{@greeting}!" end # POST /hello request r.post do puts "Someone said #{@greeting}!" r.redirect end end end end end run App.freeze.app
動作確認
Roda は Rack ベースなので、動かすには rackup するだけです。今回は環境としては Cloud9 で EC2 インスタンス上で動作させています。
$ rackup Puma starting in single mode... * Version 3.12.0 (ruby 2.6.0-p0), codename: Llamas in Pajamas * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://localhost:9292 Use Ctrl-C to stop
9292ポートでアプリケーションが実行されるので、 curl でリクエストを投げてみると、下記のようにレスポンスが返ります。
$ curl localhost:9292/hello
Hello!
ログには下記のように出力されます。
127.0.0.1 - - [30/Mar/2019:12:55:59 +0000] "GET /hello HTTP/1.1" 200 6 0.0005
サンプルアプリの内容
Roda ではリクエストのルーティングはルーティングツリーと呼ばれる構成で管理されています。 config.ru で定義した内容がルーティングツリーになりますので、その設定内容を簡単に説明します。
まず r.root
はルートパス /
への GET リクエストのみマッチします。
# GET / request r.root do r.redirect '/hello' end
curl では下記のようにリクエストを投げます。
$ curl localhost:9292/
127.0.0.1 - - [30/Mar/2019:13:09:27 +0000] "GET / HTTP/1.1" 302 - 0.0011
/hello
というリクエストについては下記のブロックで定義しています。
# /hello branch r.on 'hello' do ・・・ end
その中でさらに下層のパスへの設定も行います。 /hello/world
への GET リクエストについては下記のように定義します。
r.get 'world' do "#{@greeting} world!" end
リクエストを投げると下記のように動作します。
$ curl localhost:9292/hello/world
Hello world!
127.0.0.1 - - [30/Mar/2019:13:22:26 +0000] "GET /hello/world HTTP/1.1" 200 12 0.0013
/hello
の下層のパスがないリクエストの場合は下記の設定がマッチします。
# /hello request r.is do ・・・ end
/hello
に GET リクエストが投げられた場合の設定は下記の内容になります。
r.get do "#{@greeting}!" end
$ curl localhost:9292/hello
Hello!
127.0.0.1 - - [30/Mar/2019:13:28:37 +0000] "GET /hello HTTP/1.1" 200 6 0.0014
また、 POST リクエストの場合は下記のブロックの設定になります。
# POST /hello request r.post do puts "Someone said #{@greeting}!" r.redirect end
$ curl -X POST localhost:9292/hello
Someone said Hello! 127.0.0.1 - - [30/Mar/2019:13:30:27 +0000] "POST /hello HTTP/1.1" 302 - 0.0013
まとめ
今回はとりあえずサンプルをそのまま動かしただけでしたが、公式サイトには他にも様々な Matcher の書き方が紹介されています。 Rails を使っていると基本的な技術要素というよりは "Railsの使い方" に視点が行きがちだと思いますが、こういったコア機能のみ提供しているシンプルなフレームワークをベースにアプリケーションを作っていくとなると、 Rack や各個別の技術要素を改めて意識するきっかけになりそうで良いですね。