4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Crystal][Kemal] ルート指定でスプラット(*)を使う

Last updated at Posted at 2016-01-30

Crystal 関係の情報を拾ってるとWebフレームワークの Kemal が超イケてるぽいので,Rubyのベタ書きCGIな個人サイトを Kemal で再構築してみようと試行錯誤中。

その中で,階層数を特定せず複数階層("a", "a/b", "a/b/c", ...)全体にマッチするルートを指定する必要にかられたのですがKemalのドキュメントを見てもそれらしい記述が見当たりません。

Kemalのインスパイア元であるSinatraのドキュメントを当たってみる,とどうやらスプラット(*)を使えば良いっぽいので,

Sinatra
get '/download/*.*' do
  # matches /download/path/to/file.xml
  params['splat'] # => ["path/to/file", "xml"]
end

モノは試しとKemalで

Kemal
# access to http://localhost:3000/test1/test2/test3
get "/*" do |env|
  env.params["splat"]
end

とやってみたら,案の定Exception: Missing hash key: "splat"と怒られた。

その後,Kemalのソースを追いかけてパスツリーの検索にRadix::Tree#findが使われていることを突き止め,さらにRadixのソースを追いかけてみると,コロン(:)を使ったパラメータ名指定と同じように,スプラットの後にもパラメータ名を指定できるようで,↓みたいにすれば良いらしい。

Kemal
# access to http://localhost:3000/test1/test2/test3
get "/*path" do |env|
  env.params["path"] # => "test1/test2/test3"
end

スプラットが複数出てくる時に別の名前を指定できるので,Sinatraの指定のキーで配列が返ってくる仕様より便利かも。

Kemal(Radix)超イカス!!

で余談ですが,スプラットの後ろの文字列がパラメータ名になるため,明示的なパラメータ名をつけず”*"とだけ指定すると,名前が空文字("")のパラメータとして設定されるみたい。下の例みたいにルートパス以下を全部引っ掛けるような時ならコレでも良いかも。

Kemal
# access to http://localhost:3000/test1/test2/test3
get "/*" do |env|
  env.params[""] # => "test1/test2/test3"
end

追記

ルート(route)に "/*" を指定すると,env.params[""] にはリクエストパスからルート(root)パスである先頭の / を除いた文字列が格納されます。

get "/*" do |env|
  env.params[""] # http://localhost:3000/aaa/bbb/ccc => "aaa/bbb/ccc"
end 

サイトのルートパス(/)にアクセスしたら場合には空文字を返してくれるかと思ったら,どうやらこのルートは / にはマッチしない模様。

それじゃ "*" を指定すれば先頭の / も含んだリクエストパス全体が帰ってくんじゃないかと試しましたが,こちらはどのパスに対してもマッチしないルートになってしまいました。

get "*" do |env|
  env.params[""] # http://localhost:3000/            => 404 Error
                 # http://localhost:3000/aaa/bbb/ccc => 404 Error
end 

さしあたりルートパスのルートは独立して指定するしかなさそうですね。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?