Class: Hollow::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/hollow/application.rb

Overview

A RESTful service provider framework which provides dynamic access to REST resource objects, allowing routers to service reqeusts without any knowledge of the types that exist in business code.

  • Resource classes compose the service provider aspect of Hollow and

encapsulate all or part of a system’s business logic.

  • Any class can be registered as a resource by including one of the

Stateless or Stateful modules.

  • The service provider API is defined dynamically by application instance

configuration (see settings). Different application instances can use the same underlying resources, but they will filter access to those resources differently. Requests through one application instance may succeed while requests through another may raise access exceptions.

  • Application instances provide service access to resources via the

handle_request method.

Defined Under Namespace

Classes: ResourceException, ResourceMethodException

Constant Summary collapse

DEFAULT_SETTINGS =

Default application settings.

{
  autorequire: {
    root: "#{File.dirname __FILE__}/../..",
    directories: []
  },
  resource_methods: ["get", "post", "put", "patch", "delete", "options"]
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(settings = {}) ⇒ Application

Create a new application instance.

Parameters:

  • settings (Hash) (defaults to: {})

    application settings. See DEFAULT_SETTINGS for defaults.

Options Hash (settings):

  • :resource_methods (Array<Symbol>, Array<String>)

    Resource method names which may be invoked on resource instances by this application. This effectively defines the service provider API.

  • :autorequire[:root] (String)

    location in the file system relative to which other filesystem locations are evaluated.

  • :autorequire[:directories] (Array<String>)

    file system locations where resource classes may be found; all classes in these directories will be required immediately. These locations are relative to ‘:autorequire`.



80
81
82
83
84
85
86
# File 'lib/hollow/application.rb', line 80

def initialize(settings = {})
  @settings = DEFAULT_SETTINGS.merge(settings)
  @settings[:resource_methods].map! { |m| m.to_sym }
  @settings[:autorequire][:directories].each do |dir|
    require_all "#{@settings[:autorequire][:root]}/#{dir}"
  end
end

Instance Attribute Details

#settingsHash (readonly)

Returns the application settings.

Returns:

  • (Hash)

    the application settings



65
66
67
# File 'lib/hollow/application.rb', line 65

def settings
  @settings
end

Instance Method Details

#handle_request(resource: nil, method: nil, data: {}) ⇒ Object

Attempt to invoke a resource method with the given data.

Parameters:

  • resource (String, Symbol) (defaults to: nil)

    The case-sensitive name of a desired resource.

  • method (String, Symbol) (defaults to: nil)

    The case-sensitive resource method name to invoke.

  • data (Hash) (defaults to: {})

    Any data which the resource may or may not use to handle the reqeust.

Raises:

  • (ResourceException)

    If the indicated resource is not defined, is not a Class, is Resource itself, or is not a type of Resource.

  • (ResourceMethodException)

    If the indicated resource exists and:

    1. The indicated method is not accessible or defined, or
    2. The method name is not included in `settings[:resource_methods]`.
    


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/hollow/application.rb', line 103

def handle_request(resource: nil, method: nil, data: {})
  begin
    resource_class = Application::get_resource(resource.to_sym)
    handler = resource_class.get_instance
    method = method.to_sym.downcase
  rescue NoMethodError, NameError
    fail ResourceException.new resource
  end

  if @settings[:resource_methods].include?(method) &&
      handler.respond_to?(method)
    invoke_chain(resource_class, data, :before, method)
    response = handler.public_send(method, data)
    invoke_chain(resource_class, data, :after, method)
    return response
  else
    fail ResourceMethodException.new resource, method
  end
end