Class: Vayacondios::Server::Api

Inherits:
Goliath::API
  • Object
show all
Includes:
ApiOptions
Defined in:
lib/vayacondios/server/api.rb

Overview

Implements the Vayacondios server API.

## Setup

Once the Goliath server has booted, this class is handed control to process web requests. It uses a set of Rack-aware and Goliath-friendly plugins to accomplish some of the edges stuff like routing, parsing params, validating, &c.

## Request Loop

When handling an actual request, it has to do four things:

  • determine which handler class to instantiate to handle the request

  • determine the full set of params contained in the request

  • call the appropriate method on the new handler, passing in these params

  • handle any errors that bubble up

## Configuration

Goliath is kind of weirdly hard to configure nicely. This class is also required to define an #options_parser method which is momentarily handed control at bootup time to interpret options passed to the ‘vcd-server` program.

It simultaneously is required to read a configuration file from disk. This configuration file is aware of the Rack environment the code is running in so it can take environment-specific actions like creating single-connections in test/development but using a pool of shared connections in production mode. The default file is located in the Vayacondios source distribution at ‘config/vcd-server.rb`.

Instance Method Summary collapse

Methods included from ApiOptions

#options_parser

Instance Method Details

#documentHash, ...

The document part of the request, e.g. - params that came directly from its body.

Goliath::Rack::Params dumps all non-Hash types that were JSON parsed under this header. By accessing the #document this way we allow for non-Hash bodies to be sent as requests.

Returns:

  • (Hash, Array, String, Fixnum, nil)

    any native JSON datatype



81
82
83
# File 'lib/vayacondios/server/api.rb', line 81

def document
  params.has_key?('_json') ? params['_json'] : params
end

#on_close(env) ⇒ Object

Make sure to remove any outstanding streaming connections when the client disconnects



93
94
95
96
# File 'lib/vayacondios/server/api.rb', line 93

def on_close env
  return unless env[:subscription]
  env.delete(:subscription).close_stream!
end

#open_stream(env, hndlr) ⇒ Object

Assign a callback to the stream endpoint. Some of the Rack logic is recreated because of the way streaming data works.



87
88
89
# File 'lib/vayacondios/server/api.rb', line 87

def open_stream(env, hndlr)
  env[:subscription] = hndlr.stream_data{ |data| env.stream_send MultiJson.dump(data).concat("\n") }
end

#response(env) ⇒ Object

Deliver a response for the request.

Uses the method set by Infochimps::Rack::ControlMethods to determine which action to call on the handler determined by Infochimps::Rack::Validation::RouteHandler

Traps Goliath::Validation::Errors by returning the appropriate response.

Traps all other errors by responding with a 500.

Parameters:

  • env (Hash)

    the current request environment



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/vayacondios/server/api.rb', line 110

def response env
  h = handler.new(logger, db)
  open_stream(env, h) if routes[:type] == 'stream'
  body = h.call(control_method, routes, document)
  [200, {}, body]
rescue Goliath::Validation::Error => e
  return [e.status_code, {}, { error: e.message }]
rescue Document::Error => e
  return [400, {}, { error: e.message }]
rescue => e
  logger.error "#{e.class} -- #{e.message}"
  e.backtrace.each{ |line| logger.error line }
  return [500, {}, { error: "#{e.class} -- #{e.message}" }]
end