patorashのブログ

方向性はまだない

Railsで作ってたアプリをSinatraで作り直した

何年も前に社内向けにシンプルなアプリをRailsで作っていたのだけれど、長いことメンテナンスできずにいた。 Rubyのバージョンも古いし、Railsのバージョンも古かったので、バージョンアップをしないとなぁと思っていたのだけれど、やったところでまた数年後に同じ思いをすることになりそうだなぁ…と思ったので、もっとバージョンアップのしやすいSinatraに書き換えることにした。

実はSinatraを試したことくらいはあったけれど、ちゃんとデプロイまでしたことはなかったので、よい経験になった。

作ったもの

シンプルなWebAPIを作った。JSONを返すだけ。

使ったgem

ハマったところ

CORSをするための設定

CORSをするときに、Bearer認証を使っていたため、Authorizationヘッダーを追加しているのでpreflight requestが発生するようになり、エラーが発生していた。

Before
# app.rb
require 'sinatra'
require 'sinatra/activerecord'
require 'sinatra/contrib'
require "sinatra/cors"
require 'rack/bearer_auth'

use Rack::BearerAuth::Middleware do
  match path: "/api/v1/foos", via: [:all] do |token|
    AccessToken.exists?(token: token)
  end
end

set :database_file, 'config/database.yml'
set :allow_origin, '*'
set :allow_methods, 'GET'
set :allow_headers, 'content-type,if-modified-since'
set :allow_credentials, true

# 略
After

調査をした結果、以下の修正が必要だった。

# app.rb
require 'sinatra'
require 'sinatra/activerecord'
require 'sinatra/contrib'
require "sinatra/cors"
require 'rack/bearer_auth'

use Rack::BearerAuth::Middleware do
  match path: "/api/v1/foos", via: [:get] do |token| # <= via: [:get]に変更してoptionsの場合を対象外に変更
    AccessToken.exists?(token: token)
  end
end

set :database_file, 'config/database.yml'
set :allow_origin, '*'
set :allow_methods, 'GET,OPTIONS' # <= OPTIONSを追加
set :allow_headers, 'content-type,if-modified-since,authorization' # <= authorizationを追加
set :allow_credentials, true

# 略

これでCORSできるようになった!

最初のCORSの設定を行ったとき、当初はBearer認証を実装してない状態だったのでシンプルなCORSでpreflight requestが発生していなかったので気づかなかった。 Bearer認証を実装したときには、CORSを試さずに単にREST Clientで試して問題なかったので、気づかなかった。 普通にデプロイ後に一応手動テストを行ったらCORSに失敗して非常に焦った…😅

pumaコマンドでsinatraの起動

pumaコマンドで起動する場合、config.ruファイルが必要。

# config.ru
require './app'
run Sinatra::Application

ホットリロードの導入

単にpumaで起動した場合、ファイルを修正しても反映されないので、一旦pumaを止めてまた起動しなければならない。

bundle exec puma

rerunを使うことで、ファイルを修正したらホットリロードされるようになる。

bundle exec rerun puma

修正が即反映されてとっても捗る。

まとめ

これでRailsアプリを1つメンテナンスしなくて済むようになったのでよかった。Sinatraならメンテ不要というわけでもないけれど、まぁ基本的にbundle updateだけで済みそうでしょう。

久々にブログを書いたけれど、やっぱりメモ的な内容でもいいからアウトプットしていかないとなぁ〜と思った。管理職になってからコードを書く量がめちゃ減っているので頑張っていきたい。