Source Adapter Controller API (Ruby)

Your RhoConnect source adapter controller can use any of these methods to facilitate handling of the incoming requests.

register Rhoconnect::EndPoint

Rhoconnect::EndPoint is a Sinatra extension which adds the Controller into the application’s URLMap. The Source Adapter Controller becomes available at the root path /app/v1/<Source Adapter's Name>. One exception here is the Application Controller - which has its own special root /rc/v1/app. All of the Controller’s routes are registered relative to its root, for example:

GET ‘/my_custom_route’ declared inside of the Product Controller expands into GET ‘/app/v1/Product/my_custom_route’

You can see which routes are available for your application by using `rhoconnect routes` command inside of your app's root directory.

register Rhoconnect::Handler::Sync

Rhoconnect::Handler::Sync is a Sinatra extension which adds default SYNC routes into your Source Adapter Controller. When used, it adds the following routes into the Source Adapter Controller:

GET '/' Main SYNC route responsible for data query and downloading the changes to the client. Handler: :rc_handler => :query Options: :source_required => true, :client_required => true, :login_required => true
POST '/' Create/Update/Delete route responsible for handling incoming changes (creates/updates/deletes) from the client. Handler: :rc_handler => :cud Options: :source_required => true, :client_required => true, :login_required => true
PUT '/:id' Update route responsible for updating a single object from the client. Handler: :rc_handler => :update Options: :source_required => true, :client_required => true, :login_required => true
DELETE '/:id' Update route responsible for deleting a single object from the client. Handler: :rc_handler => :delete Options: :source_required => true, :client_required => true, :login_required => true

Also, the Rhoconnect::Handler::Sync extension adds the following Plugin Callback routes (requires API Token):

POST '/push_objects' This route is used to upload changes (creates or updates) from the plugin (or any 3rd party application). Handler: :rc_handler => :push_objects Options: :admin_required => true
POST '/push_deletes' This route is used to delete objects (called from the plugin or any 3rd party application). Handler: :rc_handler => :push_deletes Options: :admin_required => true

@model

@model variable is available implicitly only inside of the Source Adapter Controller’s routes that enforce :source_required => true condition (which in turn requires valid session cookie upon the call). Access your source adapter model instance variable inside of the route:

post '/my_custom_route', :source_required => true do
  "Hello! I am - #{@model.source.inspect}"
end
Application Controller doesn't have the @model variable available, since it is not a Source Adapter Controller.

Alternatively, you can construct the model’s instance by using the following method inside of your route:

post '/my_custom_route' do
    source_instance = Source.load('<source_name>',
        {:user_id => '<username>', :app_id => Rhoconnect::APP_NAME}
    @model = Rhoconnect::Model::Base.create(source_instance)
    "Hello! I am - #{@model.source.inspect}"
end

Here:

source_name name of the source that you want to load (for example, Product). Source here can be considered as the model's run-time meta context.
username name of the user whose source data you want to load. Source (and model) always operate in the context of a certain user.

Sinatra context

You can access and use any of the standard Sinatra objects defined in the context of the request: params, request, response, etc.

post '/my_custom_route'
  log params.inspect
  response.headers['my_ret_header'] = 'This is my response header'
  status 200
 end

Sinatra framework

Source adapter controller is a Sinatra app - you can use any of the standard Sinatra features:

Look for more info in the Sinatra documentation

In the below example, you can register and use custom defined logger.

module MyCustomLogger
  def my_custom_log(message)
    # do some interesting stuff here
  end
end

class Product < Rhoconnect::Controller::Base
  helpers MyCustomLogger

  # use my_custom_log before the route is called
  before '/my_custom_route' do
    my_custom_log("Calling from before")
  end

  # route definitions
  post '/my_custom_route' do
    'Hello World'
  end
end

Pre-defined conditions

Some of the most commonly used features and helpers are exposed to the user via pre-defined Sinatra conditions.

For more info on what is Sinatra condition and how to use it - look here

admin_required

When installed, this condition enforces presence of the api-token, thus, making the route accessible only to the admin user. Typically, all system routes using this condition:

post '/my_custom_admin_route', :admin_required => true do
    puts 'Only admin can access this route'
end

login_required

When installed, this condition enforces presence of the Session Cookie, i.e. only logged-in user can access this route. Typically, this condition enabled by default for all user-defined Controllers. If want to alter this behavior, you can enable/disable this condition for any particular route:

get '/my_custom_route', :login_required => false do
    puts 'Hello World - no user required to access this route'
end

source_required

When installed, this condition enforces presence of the source_id. This condition is enabled by default for all user-defined Controllers - since they by definition based upon Source. To customize behavior of your route - you can disable this check and load any desired sources manually inside of your route. Also, this condition initializes @model variable:

get '/my_custom_route', :source_required => false do
    other_source = Source.load('<source_name>',
        {:user_id => '<username>', :app_id => Rhoconnect::APP_NAME}
    other_model = Rhoconnect::Model::Base.create(other_source)
    puts "Hello World - using my #{other_model.inspect}"
end

client_required

When installed, this condition enforces presense of the client_id. This condition is enabled by default for all sync routes - because they are called from the client. Also, client_required condition implicitly enforces presence of the source_id parameter and therefore is used together with source_required condition. You may enable/disable it in your custom route:

post '/my_custom_route_many_sources', :client_required => false, :source_required => false, :login_required => false, :admin_required => true do
    puts "Admin is required here - this is my admin route and client is not required!"
    # my custom sources_data is a JSON hash-table 
    user_name = @params['username']
    sources_data = @params['sources_data']
    sources_data.each do |source_name, source_data|
        # do something with data
    end
end

verbs

You can use this helper condition whenever you need to make some functionality available only to routes with specific verbs. Typically, this can be helpful in your custom :before or :after filters. For example, if you have two routes using the same path, but different verbs (POST and GET) and you want to execute :before filter only for the GET route:

class Product < Rhoconnect::Controller::Base
  # use my_custom_log before the route is called
  before '/my_custom_route', :verbs => ['GET'] do
    puts "This code will be executed only before the GET route"
  end

  # route definitions
  post '/my_custom_route' do
    puts 'my POST route'
  end

  get 'my_custom_route' do
    puts 'My GET route'
  end
end

default settings

Every user-defined Source Adapter Controller has certain conditions enabled by default. This means that whenever you’re defining your custom route inside of the Source Adapter Controller, it will implicitly install several conditions. Below is the list of the conditions installed by default:

* :source_required => true
* :client_required => true
* :login_required => true
If you want disable one of predefined conditions, then you should do it manually inside of your custom routes declaration.
Back to Top