Class: Goliath::API
- Inherits:
-
Object
- Object
- Goliath::API
- Includes:
- Constants, Rack::Validator
- Defined in:
- lib/goliath/api.rb
Overview
All Goliath APIs subclass Goliath::API. All subclasses must override the #response method.
Direct Known Subclasses
Constant Summary
Constants included from Constants
Constants::ASYNC_BODY, Constants::ASYNC_CALLBACK, Constants::ASYNC_CLOSE, Constants::ASYNC_HEADERS, Constants::CONFIG, Constants::CONNECTION, Constants::CONTENT_LENGTH, Constants::CONTENT_TYPE, Constants::FRAGMENT, Constants::GOLIATH_ENV, Constants::GOLIATH_SIGNATURE, Constants::HTTP_PREFIX, Constants::HTTP_VERSION, Constants::INITIAL_BODY, Constants::LOCALHOST, Constants::OPTIONS, Constants::PATH_INFO, Constants::QUERY_STRING, Constants::RACK_ERRORS, Constants::RACK_EXCEPTION, Constants::RACK_INPUT, Constants::RACK_LOGGER, Constants::RACK_MULTIPROCESS, Constants::RACK_MULTITHREAD, Constants::RACK_RUN_ONCE, Constants::RACK_URL_SCHEME, Constants::RACK_VERSION, Constants::RACK_VERSION_NUM, Constants::REMOTE_ADDR, Constants::REQUEST_METHOD, Constants::REQUEST_PATH, Constants::REQUEST_URI, Constants::SCRIPT_NAME, Constants::SERVER, Constants::SERVER_NAME, Constants::SERVER_PORT, Constants::SERVER_SOFTWARE, Constants::STATUS, Constants::STREAM_CLOSE, Constants::STREAM_SEND, Constants::STREAM_START, Constants::UPGRADE_DATA
Class Method Summary collapse
-
.inherited(subclass) ⇒ Object
Catches the userland class which inherits the Goliath API.
-
.middlewares ⇒ Array
Retrieves the middlewares defined by this API server.
-
.plugin(name, *args) ⇒ Object
Specify a plugin to be used by the API.
-
.plugins ⇒ Array
Returns the plugins configured for this API.
-
.use(name, *args, &block) ⇒ Object
Specify a middleware to be used by the API.
Instance Method Summary collapse
- #call(env) ⇒ Goliath::Connection::AsyncResponse
-
#chunked_streaming_response(status_code = 200, headers = {}) ⇒ Object
Helper method for chunked transfer streaming response apis.
-
#env ⇒ Goliath::Env
Accessor for the current env object.
-
#initialize(opts = {}) ⇒ API
constructor
The default constructor does nothing with the options passed, redefine your own to use them.
-
#method_missing(name, *args, &blk) ⇒ Object
The API will proxy missing calls to the env object if possible.
-
#options_parser(opts, options) ⇒ Object
Default stub method to add options into the option parser.
-
#respond_to_missing?(name) ⇒ Boolean
True if the API’s method_missing responds to the method.
-
#response(env) ⇒ Array
Response is the main implementation method for Goliath APIs.
-
#streaming_response(status_code = 200, headers = {}) ⇒ Object
Helper method for streaming response apis.
Methods included from Rack::Validator
Constructor Details
#initialize(opts = {}) ⇒ API
The default constructor does nothing with the options passed, redefine your own to use them.
103 104 105 |
# File 'lib/goliath/api.rb', line 103 def initialize(opts = {}) @opts = opts end |
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.
138 139 140 141 142 143 144 145 |
# File 'lib/goliath/api.rb', line 138 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
.inherited(subclass) ⇒ Object
Catches the userland class which inherits the Goliath API
In case of further subclassing, the very last class encountered is used.
28 29 30 |
# File 'lib/goliath/api.rb', line 28 def inherited(subclass) Goliath::Application.app_class = subclass.name if defined?(Goliath::Application) end |
.middlewares ⇒ Array
Retrieves the middlewares defined by this API server
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/goliath/api.rb', line 35 def middlewares @middlewares ||= [] unless @loaded_default_middlewares @middlewares.unshift([::Goliath::Rack::DefaultResponseFormat, nil, nil]) @middlewares.unshift([::AsyncRack::ContentLength, nil, nil]) if Goliath.env?(:development) && !@middlewares.detect {|mw| mw.first == ::Rack::Reloader} @middlewares.unshift([::Rack::Reloader, 0, nil]) end @loaded_default_middlewares = true end @middlewares end |
.plugin(name, *args) ⇒ Object
Specify a plugin to be used by the API
92 93 94 |
# File 'lib/goliath/api.rb', line 92 def plugin(name, *args) plugins.push([name, args]) end |
.plugins ⇒ Array
Returns the plugins configured for this API
81 82 83 |
# File 'lib/goliath/api.rb', line 81 def plugins @plugins ||= [] end |
.use(name, *args, &block) ⇒ Object
Specify a middleware to be used by the API
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/goliath/api.rb', line 64 def use(name, *args, &block) @middlewares ||= [] if name == Goliath::Rack::Render [args].flatten.each do |type| type = Goliath::Rack::Formatters.const_get type.upcase @middlewares << [type, nil, nil] end end @middlewares << [name, args, block] @middlewares = @middlewares.uniq end |
Instance Method Details
#call(env) ⇒ Goliath::Connection::AsyncResponse
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/goliath/api.rb', line 160 def call(env) begin Thread.current[GOLIATH_ENV] = env status, headers, body = response(env) if status if body == Goliath::Response::STREAMING env[STREAM_START].call(status, headers) else env[ASYNC_CALLBACK].call([status, headers, body]) end end rescue Goliath::Validation::Error => e env[RACK_EXCEPTION] = e env[ASYNC_CALLBACK].call(validation_error(e.status_code, e., e.headers)) rescue Exception => e logthis = "#{e.backtrace[0]}: #{e.} (#{e.class})\n" e.backtrace[1..-1].each do |bt| logthis += " from #{bt}\n" end env.logger.error(logthis) env[RACK_EXCEPTION] = e = Goliath.env?(:production) ? 'An error happened' : e. env[ASYNC_CALLBACK].call(validation_error(500, )) end Goliath::Connection::AsyncResponse end |
#chunked_streaming_response(status_code = 200, headers = {}) ⇒ Object
Helper method for chunked transfer streaming response apis
Chunked transfer streaming is transparent to all clients (it’s just as good as a normal response), but allows an aware client to begin consuming the stream even as it’s produced.
If you are using chunked streaming, you must use env.chunked_stream_send and env.chunked_stream_close
229 230 231 |
# File 'lib/goliath/api.rb', line 229 def chunked_streaming_response(status_code = 200, headers = {}) streaming_response(status_code, headers.merge(Goliath::Response::CHUNKED_STREAM_HEADERS)) end |
#env ⇒ Goliath::Env
This will not work in a streaming server. You must pass around the env object.
Accessor for the current env object
125 126 127 |
# File 'lib/goliath/api.rb', line 125 def env Thread.current[GOLIATH_ENV] end |
#options_parser(opts, options) ⇒ Object
Default stub method to add options into the option parser.
117 118 |
# File 'lib/goliath/api.rb', line 117 def (opts, ) end |
#respond_to_missing?(name) ⇒ Boolean
Returns True if the API’s method_missing responds to the method.
149 150 151 |
# File 'lib/goliath/api.rb', line 149 def respond_to_missing?(name, *) env.respond_to? name 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.
200 201 202 203 |
# File 'lib/goliath/api.rb', line 200 def response(env) env.logger.error('You need to implement response') raise Goliath::Validation::InternalServerError.new('No response implemented') end |
#streaming_response(status_code = 200, headers = {}) ⇒ Object
Helper method for streaming response apis.
209 210 211 |
# File 'lib/goliath/api.rb', line 209 def streaming_response(status_code = 200, headers = {}) [status_code, headers, Goliath::Response::STREAMING] end |