Class: Goliath::API

Inherits:
Object
  • Object
show all
Defined in:
lib/goliath/api.rb

Overview

All Goliath APIs subclass Goliath::API. All subclasses must override the #response method.

Examples:

require 'goliath'

class HelloWorld < Goliath::API
  def response(env)
    [200, {}, "hello world"]
  end
end

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &blk) ⇒ Object

The API will proxy missing calls to the env object if possible.

The two entries in this example are equivalent as long as you are not in a streaming server.

Examples:

logger.info "Hello"
env.logger.info "Hello"


113
114
115
116
117
118
119
120
# File 'lib/goliath/api.rb', line 113

def method_missing(name, *args, &blk)
  name = name.to_s
  if env.respond_to?(name)
    env.send(name, *args, &blk)
  else
    super(name.to_sym, *args, &blk)
  end
end

Class Method Details

.map(name, &block) ⇒ Object

Specify a router map to be used by the API

Examples:

map '/version' do
  run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Version 0.1"]] }
end

Parameters:

  • name (String)

    The URL path to map

  • block

    The code to execute



77
78
79
# File 'lib/goliath/api.rb', line 77

def map(name, &block)
  maps.push([name, block])
end

.mapsArray

Returns the router maps configured for the API

Returns:

  • (Array)

    array contains [path, block]



64
65
66
# File 'lib/goliath/api.rb', line 64

def maps
  @maps ||= []
end

.middlewaresArray

Retrieves the middlewares defined by this API server

Returns:

  • (Array)

    array contains [middleware class, args, block]



22
23
24
25
# File 'lib/goliath/api.rb', line 22

def middlewares
  @middlewares ||= [[::Rack::ContentLength, nil, nil],
                    [Goliath::Rack::DefaultResponseFormat, nil, nil]]
end

.plugin(name, *args) ⇒ Object

Specify a plugin to be used by the API

Examples:

plugin Goliath::Plugin::Latency

Parameters:

  • name (Class)

    The plugin class to use

  • args

    The arguments to the plugin



57
58
59
# File 'lib/goliath/api.rb', line 57

def plugin(name, *args)
  plugins.push([name, args])
end

.pluginsArray

Returns the plugins configured for this API

Returns:

  • (Array)

    array contains [plugin name, args]



46
47
48
# File 'lib/goliath/api.rb', line 46

def plugins
  @plugins ||= []
end

.use(name, args = nil, &block) ⇒ Object

Specify a middleware to be used by the API

Examples:

use Goliath::Rack::Validation::RequiredParam, {:key => 'echo'}

use ::Rack::Rewrite do
  rewrite %r{^(.*?)\??gziped=(.*)$}, lambda { |match, env| "#{match[1]}?echo=#{match[2]}" }
end

Parameters:

  • name (Class)

    The middleware class to use

  • args (defaults to: nil)

    Any arguments to pass to the middeware

  • block

    A block to pass to the middleware



39
40
41
# File 'lib/goliath/api.rb', line 39

def use(name, args = nil, &block)
  middlewares.push([name, args, block])
end

Instance Method Details

#call(env) ⇒ Goliath::Connection::AsyncResponse

#call is executed automatically by the middleware chain and will setup the environment for the #response method to execute. This includes setting up a new Fiber, handing any execptions thrown from the API and executing the appropriate callback method for the API.

Parameters:

Returns:

  • (Goliath::Connection::AsyncResponse)

    An async response.



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/goliath/api.rb', line 129

def call(env)
  Fiber.new {
    begin
      Thread.current[Goliath::Constants::GOLIATH_ENV] = env
      status, headers, body = response(env)

      if body == Goliath::Response::STREAMING
        env[Goliath::Constants::STREAM_START].call(status, headers)
      else
        env[Goliath::Constants::ASYNC_CALLBACK].call([status, headers, body])
      end

    rescue Exception => e
      env.logger.error(e.message)
      env.logger.error(e.backtrace.join("\n"))

      env[Goliath::Constants::ASYNC_CALLBACK].call([400, {}, {:error => e.message}])
    end
  }.resume

  Goliath::Connection::AsyncResponse
end

#envGoliath::Env

Note:

This will not work in a streaming server. You must pass around the env object.

Accessor for the current env object

Returns:

  • (Goliath::Env)

    The current environment data for the request



100
101
102
# File 'lib/goliath/api.rb', line 100

def env
  Thread.current[Goliath::Constants::GOLIATH_ENV]
end

#options_parser(opts, options) ⇒ Object

Default stub method to add options into the option parser.

Examples:

def options_parser(opts, options)
  options[:test] = 0
  opts.on('-t', '--test NUM', "The test number") { |val| options[:test] = val.to_i }
end

Parameters:

  • opts (OptionParser)

    The options parser

  • options (Hash)

    The hash to insert the parsed options into



92
93
# File 'lib/goliath/api.rb', line 92

def options_parser(opts, options)
end

#response(env) ⇒ Array

Response is the main implementation method for Goliath APIs. All APIs should override this method in order to do any actual work.

The response method will be executed in a new Fiber and wrapped in a begin rescue block to handle an thrown API errors.

Parameters:

Returns:

  • (Array)

    Array contains [Status code, Headers Hash, Body]



160
161
162
163
# File 'lib/goliath/api.rb', line 160

def response(env)
  env.logger.error('You need to implement response')
  [400, {}, {:error => 'No response implemented'}]
end