概要
VercelでRubyのランタイムもサポートされているそうなのでSinatraで作成したTodoリストアプリを動かしてみました。
実際のコードは下記になります。
※本記事はあくまで試してみたレベルですのでProdでの使用等々は自身のご判断でお願いします
前提(VercelのRuby Runtime)
VercelのRuby Runtimeの説明をみると下記のようにリクエストを受け取ってレスポンスを返すとのことでした。
ので、このリクエストをSinatraのアプリケーションに渡すことで動かすようにします。
require 'cowsay'
Handler = Proc.new do |request, response|
name = request.query['name'] || 'World'
response.status = 200
response['Content-Type'] = 'text/text; charset=utf-8'
response.body = Cowsay.say("Hello #{name}", 'cow')
end
Sinatraアプリケーションへリクエストを渡す
Sinatraは、Ruby on Railsと同様にRackを基盤に動いているので、受け取ったrequestをrackのインターフェースに合わせてSinatraのアプリケーションに渡してあげます。
※もっと良い感じに詰められるのでしょうが、最低限動くとこまで見たかったのでこうなっています
require_relative '../app/main'
Handler = Proc.new do |request, response|
app = MyApp.new
env = {
'REQUEST_METHOD' => request.request_method,
'PATH_INFO' => request.path,
'QUERY_STRING' => request.query_string,
'rack.input' => StringIO.new(request.body || "")
}
status, headers, body = app.call(env)
response.status = status
headers.each { |key, value| response[key] = value }
response.body = body.join
end
↑では簡易的に必要そうなものだけ詰めましたが、Rackのenvに関しての詳細は下記のSpecドキュメントで確認いただけます。
Sinatraのcallメソッド
参考にさせて頂いた記事
/
ベースのエンドポイントにする
verce.jsonで/
をベースにしたエンドポイントを構築します。
{
"version": 2,
"builds": [
{ "src": "api/index.rb", "use": "@vercel/ruby" }
],
"routes": [
{ "src": "/(.*)", "dest": "/api/index.rb" }
]
}
アプリケーション層での処理
ここまでできれば普通のSinatraアプリと変わらないのでドキュメントを参考にGET/POSTのエンドポイントをそれぞれ実装してみました。
require 'sinatra/base'
require 'dotenv/load'
require_relative './models/todo'
class MyApp < Sinatra::Base
get '/' do
todos = Todo.all
erb :template, locals: { todos: todos }
end
post '/add_todo' do
text = params['text']
Todo.create(text)
erb :success
end
end
その他
次はRailsのアプリケーションを動かしてみたいです。