Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial pass at doc'ing the public API

  • Loading branch information...
commit 73044bbfbcd11aa1b575fec1bc812a577efd377a 1 parent fdfe9fc
dan sinclair dj2 authored
Showing with 378 additions and 49 deletions.
  1. +3 −0  .gitignore
  2. +2 −0  .yardopts
  3. +5 −8 Rakefile
  4. +3 −0  goliath.gemspec
  5. +76 −1 lib/goliath/api.rb
  6. +6 −1 lib/goliath/application.rb
  7. +1 −0  lib/goliath/connection.rb
  8. +52 −0 lib/goliath/env.rb
  9. +16 −0 lib/goliath/goliath.rb
  10. +1 −0  lib/goliath/headers.rb
  11. +39 −38 lib/goliath/http_status_codes.rb
  12. +13 −0 lib/goliath/plugins/latency.rb
  13. +7 −0 lib/goliath/rack/default_mime_type.rb
  14. +10 −0 lib/goliath/rack/formatters/html.rb
  15. +8 −0 lib/goliath/rack/formatters/json.rb
  16. +8 −0 lib/goliath/rack/formatters/xml.rb
  17. +6 −0 lib/goliath/rack/heartbeat.rb
  18. +5 −0 lib/goliath/rack/jsonp.rb
  19. +7 −0 lib/goliath/rack/params.rb
  20. +6 −0 lib/goliath/rack/render.rb
  21. +6 −1 lib/goliath/rack/tracer.rb
  22. +17 −0 lib/goliath/rack/validation/boolean_value.rb
  23. +12 −0 lib/goliath/rack/validation/default_params.rb
  24. +18 −0 lib/goliath/rack/validation/numeric_range.rb
  25. +10 −0 lib/goliath/rack/validation/request_method.rb
  26. +12 −0 lib/goliath/rack/validation/required_param.rb
  27. +13 −0 lib/goliath/rack/validation/required_value.rb
  28. +12 −0 lib/goliath/rack/validation_error.rb
  29. +1 −0  lib/goliath/request.rb
  30. +1 −0  lib/goliath/response.rb
  31. +1 −0  lib/goliath/runner.rb
  32. +1 −0  lib/goliath/server.rb
3  .gitignore
View
@@ -7,3 +7,6 @@ pkg/
examples/log
*.swp
Gemfile.lock
+.yardoc
+.livereload
+*.watchr
2  .yardopts
View
@@ -0,0 +1,2 @@
+--main README.md
+--no-private
13 Rakefile
View
@@ -1,7 +1,7 @@
require 'bundler'
Bundler::GemHelper.install_tasks
-require 'rake/rdoctask'
+require 'yard'
require 'rspec/core/rake_task'
task :default => [:spec]
@@ -11,11 +11,8 @@ RSpec::Core::RakeTask.new('spec') do |t|
t.pattern = 'spec/**/*_spec.rb'
end
-desc 'Generate RDoc documentation'
-Rake::RDocTask.new(:rdoc) do |task|
- task.rdoc_dir = 'doc'
- task.title = 'Goliath'
- task.options = %w(--title Goliath --main README.md --line-numbers)
- task.rdoc_files.include(['lib/**/*.rb'])
- task.rdoc_files.include(['README.md', 'LICENSE'])
+desc 'Generate documentation'
+YARD::Rake::YardocTask.new do |t|
+ t.files = ['lib/**/*.rb', '-', 'LICENSE']
+ t.options = ['--main', 'README.md', '--no-private']
end
3  goliath.gemspec
View
@@ -30,6 +30,9 @@ Gem::Specification.new do |s|
s.add_development_dependency 'em-http-request'
s.add_development_dependency 'yajl-ruby'
+ s.add_development_dependency 'yard'
+ s.add_development_dependency 'bluecloth'
+
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- spec/*`.split("\n")
s.require_paths = ['lib']
77 lib/goliath/api.rb
View
@@ -2,35 +2,95 @@
require 'goliath/request'
module Goliath
+ # All Goliath APIs subclass Goliath::API. All subclasses _must_ override the
+ # {#response} method.
+ #
+ # @example
+ # require 'goliath'
+ #
+ # class HelloWorld < Goliath::API
+ # def response(env)
+ # [200, {}, "hello world"]
+ # end
+ # end
+ #
class API
-
GOLIATH_ENV = 'goliath.env'
class << self
+ # Retrieves the middlewares defined by this API server
+ #
+ # @return [Array] array contains [middleware class, args, block]
def middlewares
@middlewares ||= [[::Rack::ContentLength, nil, nil]]
end
+ # Specify a middleware to be used by the API
+ #
+ # @example
+ # use Goliath::Rack::Validation::RequiredParam, {:key => 'echo'}
+ #
+ # use ::Rack::Rewrite do
+ # rewrite %r{^(.*?)\??gziped=(.*)$}, lambda { |match, env| "#{match[1]}?echo=#{match[2]}" }
+ # end
+ #
+ # @param name [Class] The middleware class to use
+ # @param args Any arguments to pass to the middeware
+ # @param block A block to pass to the middleware
def use(name, args = nil, &block)
middlewares.push([name, args, block])
end
+ # Returns the plugins configured for this API
+ #
+ # @return [Array] array contains [plugin name, args]
def plugins
@plugins ||= []
end
+ # Specify a plugin to be used by the API
+ #
+ # @example
+ # plugin Goliath::Plugin::Latency
+ #
+ # @param name [Class] The plugin class to use
+ # @param args The arguments to the plugin
def plugin(name, *args)
plugins.push([name, args])
end
end
+ # Default stub method to add options into the option parser.
+ #
+ # @example
+ # def options_parser(opts, options)
+ # options[:test] = 0
+ # opts.on('-t', '--test NUM', "The test number") { |val| options[:test] = val.to_i }
+ # end
+ #
+ # @param opts [OptionParser] The options parser
+ # @param options [Hash] The hash to insert the parsed options into
def options_parser(opts, options)
end
+ # Accessor for the current env object
+ #
+ # @note This will not work in a streaming server. You must pass around the env object.
+ #
+ # @return [Goliath::Env] The current environment data for the request
def env
Thread.current[GOLIATH_ENV]
end
+ # 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.
+ #
+ # @example
+ # logger.info "Hello"
+ # env.logger.info "Hello"
+
def method_missing(name, *args, &blk)
name = name.to_s
if env.respond_to?(name)
@@ -40,6 +100,13 @@ def method_missing(name, *args, &blk)
end
end
+ # {#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.
+ #
+ # @param env [Goliath::Env] The request environment
+ # @return [Goliath::Connection::AsyncResponse] An async response.
def call(env)
Fiber.new {
begin
@@ -63,6 +130,14 @@ def call(env)
Goliath::Connection::AsyncResponse
end
+ # 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.
+ #
+ # @param env [Goliath::Env] The request environment
+ # @return [Array] Array contains [Status code, Headers Hash, Body]
def response(env)
env.logger.error('You need to implement response')
[400, {}, {:error => 'No response implemented'}]
7 lib/goliath/application.rb
View
@@ -1,6 +1,11 @@
-# Most of this stuff is straight out of sinatra.
module Goliath
+ # The main execution class for Goliath. This will execute in the at_exit
+ # handler to run the server.
+ #
+ # @private
class Application
+ # Most of this stuff is straight out of sinatra.
+
CALLERS_TO_IGNORE = [ # :nodoc:
/\/goliath(\/(application))?\.rb$/, # all goliath code
/rubygems\/custom_require\.rb$/, # rubygems require hacks
1  lib/goliath/connection.rb
View
@@ -2,6 +2,7 @@
require 'goliath/response'
module Goliath
+ # @private
class Connection < EM::Connection
attr_accessor :app, :request, :response
attr_reader :logger, :status, :config, :options
52 lib/goliath/env.rb
View
@@ -1,38 +1,90 @@
module Goliath
+ # Holds information for the current request.
+ #
+ # Goliath::Env also provides access to the logger, configuration information
+ # and anything else set into the config data during initialization.
class Env < Hash
+ # Create a new Goliath::Env object
+ #
+ # @return [Goliath::Env] The Goliath::Env object
def initialize
self[:start_time] = Time.now.to_f
self[:time] = Time.now.to_f
self[:trace] = []
end
+ # Add a trace timer with the given name into the environment. The tracer will
+ # provide information on the amount of time since the previous call to {#trace}
+ # or since the Goliath::Env object was initialized.
+ #
+ # @example
+ # trace("initialize hash")
+ # ....
+ # trace("Do something else")
+ #
+ # @param name [String] The name of the trace to add
def trace(name)
self[:trace].push([name, "%.2f" % ((Time.now.to_f - self[:time]) * 1000)])
self[:time] = Time.now.to_f
end
+ # Retrieve the tracer stats for this request environment. This can then be
+ # returned in the headers hash to in development to provide some simple
+ # timing information for the various API components.
+ #
+ # @example
+ # [200, {}, {:meta => {:trace => env.trace_stats}}, {}]
+ #
+ # @return [Array] Array of [name, time] pairs with a Total entry added.d
def trace_stats
self[:trace] + [['total', self[:trace].collect { |s| s[1].to_f }.inject(:+).to_s]]
end
+ # The on_close block will be executed when the connection to the client is closed.
+ # This is useful in streaming servers where we may have setup an EM::Channel or some
+ # timer that we need to be able to cancel.
+ #
+ # @example
+ # env.on_close do
+ # env.logger.info "Connection closed."
+ # end
+ #
+ # @param blk The block to execute.
def on_close(&blk)
self[Goliath::Request::ASYNC_CLOSE].callback &blk
end
+ # If the API is a streaming API this will send the provided data to the client.
+ # There will be no processing done on the data when this is called so it's the
+ # APIs responsibility to have the data formatted as needed.
+ #
+ # @param data [String] The data to send to the client.
def stream_send(data)
self[Goliath::Request::STREAM_SEND].call(data)
end
+ # If the API is a streaming API this will be executed by the API to signal that
+ # the stream is complete. This will close the connection with the client.
def stream_close
self[Goliath::Request::STREAM_CLOSE].call
end
+ # @param name [Symbol] The method to check if we respond to it.
+ # @return [Boolean] True if the Env responds to the method, false otherwise
def respond_to?(name)
return true if has_key?(name.to_s)
return true if self['config'] && self['config'].has_key?(name.to_s)
super
end
+ # The Goliath::Env will provide any of it's keys as a method. It will also provide
+ # any of the keys in the config object as methods. The methods will return
+ # the value of the key. If the key doesn't exist in either hash this will
+ # fall back to the standard method_missing implementation.
+ #
+ # @param name [Symbol] The method to look for
+ # @param args The arguments
+ # @param blk A block
def method_missing(name, *args, &blk)
return self[name.to_s] if has_key?(name.to_s)
return self['config'][name.to_s] if self['config'] && self['config'].has_key?(name.to_s)
16 lib/goliath/goliath.rb
View
@@ -1,12 +1,19 @@
+# The Goliath Framework
module Goliath
module_function
@env = 'development'
+ # Retrieves the current goliath environment
+ #
+ # @return [String] the current environment
def env
@env
end
+ # Sets the current goliath environment
+ #
+ # @param [String] env the environment string of [dev|prod|test]
def env=(env)
case(env)
when 'dev' then @env = 'development'
@@ -15,14 +22,23 @@ def env=(env)
end
end
+ # Determines if we are in the production environment
+ #
+ # @return [Boolean] true if current environemnt is production, false otherwise
def prod?
@env == 'production'
end
+ # Determines if we are in the development environment
+ #
+ # @return [Boolean] true if current environemnt is development, false otherwise
def dev?
@env == 'development'
end
+ # Determines if we are in the test environment
+ #
+ # @return [Boolean] true if current environemnt is test, false otherwise
def test?
@env == 'test'
end
1  lib/goliath/headers.rb
View
@@ -1,4 +1,5 @@
module Goliath
+ # @private
class Headers
HEADER_FORMAT = "%s: %s\r\n".freeze
ALLOWED_DUPLICATES = %w(Set-Cookie Set-Cookie2 Warning WWW-Authenticate).freeze
77 lib/goliath/http_status_codes.rb
View
@@ -1,43 +1,44 @@
module Goliath
# Every standard HTTP code mapped to the appropriate message.
- # Stolen from Mongrel.
- HTTP_STATUS_CODES = {
- 100 => 'Continue',
- 101 => 'Switching Protocols',
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Moved Temporarily',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Time-out',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Large',
- 415 => 'Unsupported Media Type',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Time-out',
+ #
+ # @author Mongrel.
+ HTTP_STATUS_CODES = {
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Moved Temporarily',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Time-out',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Large',
+ 415 => 'Unsupported Media Type',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Time-out',
505 => 'HTTP Version not supported'
}
end
13 lib/goliath/plugins/latency.rb
View
@@ -1,6 +1,18 @@
module Goliath
module Plugin
+ # Report latency information about the EventMachine reactor to the log file.
+ #
+ # @example
+ # plugin Goliath::Plugin::Latency
+ #
class Latency
+ # Called by the framework to initialize the plugin
+ #
+ # @param port [Integer] Unused
+ # @param config [Hash] The server configuration data
+ # @param status [Hash] A status hash
+ # @param logger [Log4R::Logger] The logger
+ # @return [Goliath::Plugin::Latency] An instance of the Goliath::Plugin::Latency plugin
def initialize(port, config, status, logger)
@status = status
@config = config
@@ -9,6 +21,7 @@ def initialize(port, config, status, logger)
@last = Time.now.to_f
end
+ # Called automatically to start the plugin
def run
EM.add_periodic_timer(1) do
@logger.info "LATENCY: #{Time.now.to_f - @last}"
7 lib/goliath/rack/default_mime_type.rb
View
@@ -3,6 +3,13 @@
module Goliath
module Rack
+ # Does some basic cleanup / handling of the HTTP_ACCEPT header.
+ # This will remove gzip, deflate, compressed and identity. If
+ # there are no values left the header will be set to \*/\*.
+ #
+ # @example
+ # use Goliath::Rack::DefaultMimeType
+ #
class DefaultMimeType
def initialize(app)
@app = app
10 lib/goliath/rack/formatters/html.rb
View
@@ -3,7 +3,17 @@
module Goliath
module Rack
module Formatters
+ # A simple HTML formatter. This doesn't try to be fancy and just turns
+ # Hashes into tables, Arrays into ordered lists and strings are output
+ # as HTML escaped strings.
+ #
+ # @example
+ # use Goliath::Rack::Formatters::HTML
class HTML
+ # Called by the framework to create the formatter.
+ #
+ # @param app The application
+ # @return [Goliath::Rack::Formatters::HTML] The HTML formatter
def initialize(app)
@app = app
end
8 lib/goliath/rack/formatters/json.rb
View
@@ -3,7 +3,15 @@
module Goliath
module Rack
module Formatters
+ # A JSON formatter. Uses MultiJson so you can use the JSON
+ # encoder that is right for your project.
+ #
+ # @example
+ # use Goliath::Rack::Formatters::JSON
class JSON
+ # Called by the framework to create the formatter.
+ #
+ # @return [Goliath::Rack::Formatters::JSON] The JSON formatter.
def initialize(app)
@app = app
end
8 lib/goliath/rack/formatters/xml.rb
View
@@ -3,7 +3,15 @@
module Goliath
module Rack
module Formatters
+ # A XML formatter. Attempts to convert your data into
+ # an XML document.
+ #
+ # @example
+ # use Goliath::Rack::Formatters::XML
class XML
+ # Called by the framework to create the formatter.
+ #
+ # @return [Goliath::Rack::Formatters::XML] The XML formatter.
def initialize(app)
@app = app
end
6 lib/goliath/rack/heartbeat.rb
View
@@ -1,5 +1,11 @@
module Goliath
module Rack
+ # A heartbeat mechanism for the server. This will add a _/status_ endpoint
+ # that returns status 200 and content OK when executed.
+ #
+ # @example
+ # use Goliath::Rack::Heartbeat
+ #
class Heartbeat
def initialize(app)
@app = app
5 lib/goliath/rack/jsonp.rb
View
@@ -1,5 +1,10 @@
module Goliath
module Rack
+ # A middleware to wrap the response into a JSONP callback.
+ #
+ # @example
+ # use Goliath::Rack::JSONP
+ #
class JSONP
def initialize(app)
@app = app
7 lib/goliath/rack/params.rb
View
@@ -2,6 +2,13 @@
module Goliath
module Rack
+ # A middle ware to parse params. This will parse both the
+ # query string parameters and the body and place them into
+ # the _params_ hash of the Goliath::Env for the request.
+ #
+ # @example
+ # use Goliath::Rack::Params
+ #
class Params
def initialize(app)
@app = app
6 lib/goliath/rack/render.rb
View
@@ -3,6 +3,12 @@
module Goliath
module Rack
+ # The render middleware will set the Content-Type of the response
+ # based on the provided HTTP_ACCEPT headers.
+ #
+ # @example
+ # use Goliath::Rack::Render
+ #
class Render
include ::Rack::RespondTo
7 lib/goliath/rack/tracer.rb
View
@@ -1,5 +1,10 @@
module Goliath
module Rack
+ # Middleware to inject the tracer statistics into the response headers.
+ #
+ # @example
+ # use Goliath::Rack::Tracer
+ #
class Tracer
def initialize(app)
@app = app
@@ -10,7 +15,7 @@ def call(env)
env['async.callback'] = Proc.new do |status, headers, body|
async_cb.call(post_process(env, status, headers, body))
- env.logger.info env.trace_stats.collect{|s| s.join(':')}.join(', ')
+ env.logger.info env.trace_stats.collect{|s| s.join(':')}.join(', ')
end
status, headers, body = @app.call(env)
17 lib/goliath/rack/validation/boolean_value.rb
View
@@ -1,7 +1,24 @@
module Goliath
module Rack
module Validation
+ # A middleware to validate a given value is boolean. This will attempt to do the following
+ # conversions:
+ # true = 'true' | 't' | 1
+ # false = 'false' | 'f' | 0
+ #
+ # If the parameter is not provided the :default is used.
+ #
+ # @example
+ # use Goliath::Rack::Validation::BooleanValue, {:key => 'raw', :default => false}
+ #
class BooleanValue
+ # Called by the framework to create the validator
+ #
+ # @param app The app object
+ # @param opts [Hash] The options hash
+ # @option opts [String] :key The key to access in the parameters
+ # @option opts [Boolean] :default The default value to set
+ # @return [Goliath::Rack::Validation::BooleanValue] The validator
def initialize(app, opts = {})
@app = app
@key = opts[:key]
12 lib/goliath/rack/validation/default_params.rb
View
@@ -3,7 +3,19 @@
module Goliath
module Rack
module Validation
+ # A middleware to validate that a parameter always has a value
+ #
+ # @example
+ # use Goliath::Rack::Validation::DefaultParams, {:key => 'order', :defaults => 'pubdate'}
+ #
class DefaultParams
+ # Called by the framework to create the validator
+ #
+ # @param app The app object
+ # @param opts [Hash] The options hash
+ # @option opts [String] :key The key to access in the parameters
+ # @option opts :defaults The default value to assign if the key is empty or non-existant
+ # @return [Goliath::Rack::Validation::DefaultParams] The validator
def initialize(app, opts = {})
@app = app
@defaults = opts[:defaults]
18 lib/goliath/rack/validation/numeric_range.rb
View
@@ -1,7 +1,25 @@
module Goliath
module Rack
module Validation
+ # A middleware to validate that a parameter value is within a given range. If the value
+ # falls outside the range, or is not provided the default will be used, if provided.
+ # If no default the :min or :max values will be applied to the parameter.
+ #
+ # @example
+ # use Goliath::Rack::Validation::NumericRange, {:key => 'num', :min => 1, :max => 30, :default => 10}
+ # use Goliath::Rack::Validation::NumericRange, {:key => 'num', :min => 1}
+ # use Goliath::Rack::Validation::NumericRange, {:key => 'num', :max => 10}
+ #
class NumericRange
+ # Called by the framework to create the Goliath::Rack::Validation::NumericRange validator
+ #
+ # @param app The app object
+ # @param opts [Hash] The options hash
+ # @option opts [String] :key The key to look for in the parameters
+ # @option opts [Integer] :min The minimum value
+ # @option opts [Integer] :max The maximum value
+ # @option opts [Integer] :default The default to set if outside the range
+ # @return [Goliath::Rack::Validation::NumericRange] The validator
def initialize(app, opts = {})
@app = app
@key = opts[:key]
10 lib/goliath/rack/validation/request_method.rb
View
@@ -3,11 +3,21 @@
module Goliath
module Rack
module Validation
+ # A middleware to validate that the request had a given HTTP method.
+ #
+ # @example
+ # use Goliath::Rack::Validation::RequestMethod, %w(GET POST)
+ #
class RequestMethod
attr_reader :methods
ERROR = 'Invalid request method'
+ # Called by the framework to create the Goliath::Rack::Validation::RequestMethod validator
+ #
+ # @param app The app object
+ # @param methods [Array] The accepted request methods
+ # @return [Goliath::Rack::Validation::RequestMethod] The validator
def initialize(app, methods = [])
@app = app
@methods = methods
12 lib/goliath/rack/validation/required_param.rb
View
@@ -3,9 +3,21 @@
module Goliath
module Rack
module Validation
+ # A middleware to validate that a given parameter is provided.
+ #
+ # @example
+ # use Goliath::Rack::Validation::RequiredParam, {:key => 'mode', :type => 'Mode'}
+ #
class RequiredParam
attr_reader :type, :key
+ # Creates the Goliath::Rack::Validation::RequiredParam validator
+ #
+ # @param app The app object
+ # @param opts [Hash] The validator options
+ # @option opts [String] :key The key to look for in params (default: id)
+ # @option opts [String] :type The type string to put in the error message. (default: :key)
+ # @return [Goliath::Rack::Validation::RequiredParam] The validator
def initialize(app, opts = {})
@app = app
@key = opts[:key] || 'id'
13 lib/goliath/rack/validation/required_value.rb
View
@@ -3,9 +3,22 @@
module Goliath
module Rack
module Validation
+ # Middleware to validate that a given parameter has a specified value.
+ #
+ # @example
+ # use Goliath::Rack::Validation::RequiredValue, {:key => 'mode', :values => %w(foo bar)}
+ # use Goliath::Rack::Validation::RequiredValue, {:key => 'baz', :values => 'awesome'}
+ #
class RequiredValue
attr_reader :key, :values
+ # Creates the Goliath::Rack::Validation::RequiredValue validator.
+ #
+ # @param app The app object
+ # @param opts [Hash] The options to create the validator with
+ # @option opts [String] :key The key to look for in params (default: id)
+ # @option opts [String | Array] :values The values to verify are in the params
+ # @return [Goliath::Rack::Validation::RequiredValue] The validator
def initialize(app, opts = {})
@app = app
@key = opts[:key] || 'id'
12 lib/goliath/rack/validation_error.rb
View
@@ -1,8 +1,18 @@
module Goliath
module Validation
+ # A information about exceptions raised during validation.
class Error < StandardError
+ # The status code to return from the error handler
attr_accessor :status_code
+ # Create a new Goliath::Validation::Error.
+ #
+ # @example
+ # raise Goliath::Validation::Error.new(401, "Invalid credentials")
+ #
+ # @param status_code [Integer] The status code to return
+ # @param message [String] The error message to return
+ # @return [Goliath::Validation::Error] The Goliath::Validation::Error
def initialize(status_code, message)
super(message)
@status_code = status_code
@@ -11,6 +21,8 @@ def initialize(status_code, message)
end
module Rack
+ # Middleware to catch {Goliath::Validation::Error} exceptions
+ # and returns the [status code, no headers, :error => exception message]
class ValidationError
def initialize(app)
@app = app
1  lib/goliath/request.rb
View
@@ -3,6 +3,7 @@
require 'http/parser'
module Goliath
+ # @private
class Request
attr_accessor :env, :body
attr_reader :parser
1  lib/goliath/response.rb
View
@@ -4,6 +4,7 @@
require 'time'
module Goliath
+ # @private
class Response
attr_accessor :status, :headers, :body
1  lib/goliath/runner.rb
View
@@ -4,6 +4,7 @@
require 'log4r'
module Goliath
+ # @private
class Runner
attr_accessor :address, :port, :daemonize, :verbose, :log_stdout, :log_file, :pid_file, :app, :plugins, :app_options
1  lib/goliath/server.rb
View
@@ -3,6 +3,7 @@
require 'goliath/goliath'
module Goliath
+ # @private
class Server
attr_accessor :address, :port, :logger, :app, :status, :config, :plugins, :options

3 comments on commit 73044bb

Ilya Grigorik
Owner

Great stuff.

Matt Aimonetti
Collaborator

Agreed, it's looking great, thanks for working on that Dan.

dan sinclair
Owner

You're welcome. I like inline docs, just hadn't had time to write any before.

Please sign in to comment.
Something went wrong with that request. Please try again.