best/most elegant way to share objects between a stack of rack mounted apps/middlewares?

Deadly 提交于 2020-01-01 05:23:06

问题


What is the best idiom to share an object between rack mounted applications/middlewares?

For example, this config.ru has two Sinatra apps mapped to differents endpoints:

class App1 < Sinatra::Base
  # ...
end

class App2 < Sinatra::Base
  # ...
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

Now if these two applications need to share an object, be it a database connector or any other object, what would be the best idiom for this?

I see basically two options:

1- Create a constant at the config.ru level and simply refer to that constant within the apps. For example:

SHARED_OBJECT = "hello world"

class App1 < Sinatra::Base
  get '/' do
    SHARED_OBJECT
  end
end

class App2 < Sinatra::Base
  get '/' do
    SHARED_OBJECT
  end
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

2- Create a singleton object at the config.ru level and use it within the apps. For example:

class SharedObject
  include Singleton

  def test
    @test ||= "hello world"
  end
end

class App1 < Sinatra::Base
  get '/' do
    SharedObject.instance.test
  end
end

class App2 < Sinatra::Base
  get '/' do
    SharedObject.instance.test
  end
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

Comments/suggestions?
Colin


回答1:


I would move the shared object into a separate file and namespace it. If it were a database connection object, it might look like this:

# config.ru:
require 'lib/my_app/database'
...
class App1 < Sinatra::Base
  get '/' do
    MyApp::Database.with_connection do |conn|
      ...
    end
  end
end

# lib/my_app/database:
module MyApp
  module Database
    def self.with_connection(&block)
      ...
    end
  end
end

I see this as having several benefits:

  1. it reduces the size of your config.ru file, improving readability
  2. it separates concerns -- config.ru is about Rack applications; lib/my_app/database.rb is about databases
  3. it makes it easier to extract. At some point down the line, you might want to separate App1 and App2 into separate projects and include the database connectivity as a gem. This is easy when the database code is in its own module and file.

Phrogz's comment about constants being enough and not needing singletons is wise.



来源:https://stackoverflow.com/questions/5517753/best-most-elegant-way-to-share-objects-between-a-stack-of-rack-mounted-apps-midd

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!