Architecture for a modular, component-based Sinatra Application

那年仲夏 提交于 2020-02-17 13:31:56

问题


I'm working on a Sinatra app that contains about 10 different components of functionality. We'd like to be able to mix and match these components into separate instances of the application, configured entirely from a config.yaml file that looks something like:

components:

- route: '/chunky'
  component_type: FoodLister
  component_settings: 
    food_type: bacon
    max_items: 400

- route: 'places/paris'
  component_type: Mapper
  component_settings: 
    latitude: 48.85387273165654
    longitude: 2.340087890625  

- route: 'places/losangeles'
  component_type: Mapper
  component_settings:
    latitude: 34.043556504127466
    longitude: -118.23486328125

As you can see, components can be instantiated more than once, each with their own contextual settings.

Each component consists of at least one route, with the "route" property from the config file used for the base.

What is the best way to organize and instantiate the module code?


回答1:


This is similar to include's proposal, but it doesn't require access to the rackup file.

Write your various Handlers like:

class FoodHandler < Sinatra::Base
  get '/chunky/:food' do
    "Chunky #{params[:food]}!"
  end
end

Then in your main application file:

require './lib/handlers/food_handler.rb'

class Main < Sinatra::Base
  enable :sessions
  ... bla bla bla
  use FoodHandler
end

I've used this kind of structure to build some fairly complex Sinatra apps. It scales just as well as Rails.

EDIT

To have your config file define the routes, you could do something like this:

class PlacesHandler < Sinatra::Base
  # Given your example, this would define 'places/paris' and 'places/losangeles'
  CONFIG['components'].select { |c| c['compontent_type'] == 'Mapper' }.each do |c|
    get c['route'] do
      @latitude = c['component_settings']['latitude']
      @longitude = c['component_settings']['longitude']
    end
  end
end



回答2:


TIMTOWTDI - There's_more_than_one_way_to_do_it :) and that is one. But in fact I use another way. I use Sinatra/Base to dev modular apps.

I have simgle routes to each app.

# config.ru file

require 'bundler/setup' Bundler.require(:default)

require File.dirname(__FILE__) + "/main.rb"

map "/" { run BONES::Main }

map "/dashboard" { run BONES::Dashboard }

map "/app1" { run BONES::App1 }

You can have variable sets for each instance. You can develop each 'component' on its Module.

require File.dirname(__FILE__) + "/lib/helpers.rb"

module BONES

  class Main < Sinatra::Base 
    helpers XIXA::Helpers

    configure :development do
      enable  :sessions, :clean_trace, :inline_templates
      disable :logging, :dump_errors
      set :static, true
      set :public, 'public'
    end

    enable :static, :session
    set :root, File.dirname(__FILE__)
    set :custom_option, 'hello'

    set :haml, { :format => :html5 }

    #...

That a look here. http://codex.heroku.com/

have fun :)



来源:https://stackoverflow.com/questions/7275458/architecture-for-a-modular-component-based-sinatra-application

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