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

- (Object) method_missing(name, *args, &blk)

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"


122
123
124
125
126
127
128
129
# File 'lib/goliath/api.rb', line 122

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

+ (Object) map(name, &block)

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:

  • (String) name

    The URL path to map

  • block

    The code to execute



86
87
88
# File 'lib/goliath/api.rb', line 86

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

+ (Array) maps

Returns the router maps configured for the API

Returns:

  • (Array)

    array contains [path, block]



73
74
75
# File 'lib/goliath/api.rb', line 73

def maps
  @maps ||= []
end

+ (Array) middlewares

Retrieves the middlewares defined by this API server

Returns:

  • (Array)

    array contains [middleware class, args, block]



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/goliath/api.rb', line 22

def middlewares
  @middlewares ||= []
  @middlewares.unshift([::Goliath::Rack::DefaultResponseFormat, nil, nil])
  @middlewares.unshift([::Rack::ContentLength, nil, nil])

  if Goliath.dev?
     reloader = @middlewares.detect {|mw| mw.first == ::Rack::Reloader}
     @middlewares.unshift([::Rack::Reloader, 0, nil]) if !reloader
   end

  @middlewares
end

+ (Object) plugin(name, *args)

Specify a plugin to be used by the API

Examples:

plugin Goliath::Plugin::Latency

Parameters:

  • (Class) name

    The plugin class to use

  • args

    The arguments to the plugin



66
67
68
# File 'lib/goliath/api.rb', line 66

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

+ (Array) plugins

Returns the plugins configured for this API

Returns:

  • (Array)

    array contains [plugin name, args]



55
56
57
# File 'lib/goliath/api.rb', line 55

def plugins
  @plugins ||= []
end

+ (Object) use(name, args = nil, &block)

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:

  • (Class) name

    The middleware class to use

  • args (defaults to: nil)

    Any arguments to pass to the middeware

  • block

    A block to pass to the middleware



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

def use(name, args = nil, &block)
  @middlewares ||= []
  @middlewares << [name, args, block]
end

Instance Method Details

- (Goliath::Connection::AsyncResponse) call(env)

#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:



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/goliath/api.rb', line 138

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

- (Goliath::Env) 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



109
110
111
# File 'lib/goliath/api.rb', line 109

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

- (Object) options_parser(opts, options)

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:

  • (OptionParser) opts

    The options parser

  • (Hash) options

    The hash to insert the parsed options into



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

def options_parser(opts, options)
end

- (Array) response(env)

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]



169
170
171
172
# File 'lib/goliath/api.rb', line 169

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