【Ruby】Sinatraでファイルが大きくなったので分割する

公開日:2019-05-29
最終更新:2019-05-31
※この記事は外部サイト(https://shikiyura.stars.ne.jp/blog/linux/s...)からのクロス投稿です

皆さん、Sinatra使っていますか?
簡単なWebアプリであれば一瞬でできてしまうような、Webアプリケーションフレームワークです。

しかし、簡単なので機能をたくさん増やしていたり、処理が多くなってくるとどうしても起こるのが「全体像が見えにくくなる」ということ。
機能やエンドポイントごとに分割したい、と思うこともあるでしょう。
私は思いました。
その方法を調べてみたので、まとめておきます。

例として、以下のような形でアプリケーションを作成しているとします。

# app.rb  
require 'sinatra'  
class MyApp < Sinatra::Application  
  get '/' do  
    'hello'  
  end  
end  

今回は、エンドポイントごとにファイルを分割していきます。

例1:API用のパスを作成する

追加実装する機能として、APIを作ることになったのでAPI用のURLを作成することになったとしましょう。
まず考えるのは「ブラウザ等からアクセスするパスとAPIとを分離したい」ということでしょうか。

簡単な方法としては「namespace」を使う場合です。
Sinatra::Namespace (part of Sinatra::Contrib)

# app.rb  
require 'sinatra'  
require 'sinatra/namespace' # namespaceを使うためのgem  

class MyApp < Sinatra::Application  
  namespace '/api' do  
    get '/hoge' do  
      # /api/hogeでアクセス可能  
    end  
  end  

  get '/' do  
   'hello' # 変わらず/でアクセスできる  
  end  
end  

機能ごとにnamespaceで区切ることで、機能を分けやすくなりました。
なお、namespaceは入れ子にすることができます。

namespace '/api' do  
  namespace '/v0' do  
    get '/getScore' do  
     # /api/v0/getScoreでアクセス可能  
    end  
 end  
end  

例2:機能の新旧バージョン混在

開発が進んでくると、APIや既存のパス以外に新しい処理やパスが増えていきます。
それに伴って、新しい機能と互換性のために古い機能を混在させなければいけないこともあります。
個人で作る場合も、スマホアプリとかではOSのバージョンによって使えたり使えなくなったりする機能とかで必要になるかも?わからんけど。

このような状態だと、namespaceで区切ってもファイルが大きくなってしまい、よくわからなくなってしまいます。
そこで、(タイトルにもありますが)思い切ってファイルごと分割してみます。
ドンピシャな内容が、stackoverflowに上がっていました。
ruby Using Sinatra for larger projects via multiple files Stack Overflow

# app.rb  
require 'sinatra'  
require 'sinatra/namespace'  

# 別ファイルに分割したAPIを一括で読み込む  
require_relative 'routes/init'  

class MyApp < Sinatra::Application     
  get '/' do  
    'hello'  
  end  
end  

__

# routes/init.rb  
require_relative './old_api'  
require_relative './new_api'  

__

#old_api.rb  
class MyApp < Sinatra::Application  
  namespace '/api/v0' do  
    get '/' do  
      'hello'  
    end  
  end  
end  

__

# code:new_api.rb  
class MyApp < Sinatra::Application  
  namespace '/api/v1' do  
    get '/' do  
      'hello'  
    end  
  end  
end  

これによって、新旧APIが共存した状態を作れました。
また、ファイルが分かれているので必要ないところに気にせずに作業ができますね。
(一括変換で、余計な記述を書き換えてしまったりするリスクが減ります。やったね。)

肝としては、分割したファイルをroutes/init.rbで一括で読み込んでいるところですね。
これにより、それぞれのファイルは独立しているような形で記述することができます。
もちろんすべてMyAppというクラスなので、全体で使うような処理やインスタンス変数は共有されています。
DB関連のクライアントオブジェクトなどは、メインとなるファイル側でinitializeしておき、@clientなどとして宣言しておけば、ほかのファイルからも参照できるわけですね。
便利。

まとめ

今回は、Sinatraを使った簡単なクラスの分割方法を確認しました。
この方法は、特に2つ目の例はSinatraに限らず使うことができる方法だと思います。

今回は、ここまで。
おわり

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
頭は記憶リムーバブルデバイス

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする