2020年9月28日月曜日

Sinatra の動的ルーティングを試してみた

概要

Sinatra には動的にルーティングを定義する機能があります
今回はそれを使ってデータからルーティングを定義する方法を紹介します

環境

  • macOS 10.15.6
  • Ruby 2.7.1p83
    • sinatra 2.0.7

基本

動的に Sinatara アプリケーションを作成する場合は Sinatra.new を使います
あとは作成した Sinatra インスタンスに対して run を実行します

require 'sinatra/base'
my_app = Sinatra.new { get('/') { "hi" } }
my_app.run!

データファイルを元にアプリケーションを作成

例えば json ファイルを作成してそれを元にアプリケーションを作成したりできます

  • vim data.json
[
  {
    "path": "/msg",
    "response": "hello"
  }
]
  • vim app.rb
require 'sinatra/base'

refs = JSON.load(File.read('data.json'))
my_app = Sinatra.new do 
  refs.each do |ref|
    get(ref['path']) do
      ref['response']
    end
  end
end
my_app.run!

これで /msg/user にアクセスすることができます
もし別のパスを追加したい場合は Ruby ファイルではなく json ファイルを更新するだけで追加できます

データベースを元にアプリケーションを作成することも可能

同じようにファイルではなく data.json のような値をデータベースに持ってそれをもとにルーティングを定義することもできます

config.ru で定義する場合は

rackup で起動することも可能です
controller は別ファイルで定義してもいいかもしれません

  • vim config.ru
require 'sinatra/base'

refs = JSON.load(File.read('./data.json'))

controller = Sinatra.new do
end

map('/') do
  app = Sinatra.new(controller) do
    refs.each do |ref|
      get(ref['path']) { ref['response'] }
    end
  end
  run app
end

Siantra::Reloader と組み合わせたがったがうまくいかなかった

require 'sinatra/base'
require 'sinatra/reloader'

refs = JSON.load(File.read('./data.json'))

my_app = Sinatra.new do 
  register Sinatra::Reloader
  also_reload 'data.json'

  refs.each do |ref|
    get(ref['path']) do
      ref['response']
    end
  end

end

my_app.run!

最後に

Sinatra.new を使うと動的にルーティングを定義できるのでデータなどからアプリケーションを作成することができるようになります
今回はレスポンスが固定であることを想定しているのでレスポンスも json に含めていますがレスポンスは基本的に動的に変化するのでそこはロジックを組むかそこもデータとして管理したいのであれば eval などを使えば実現できるかなと思います

参考サイト

0 件のコメント:

コメントを投稿