Class: Apia::Rack

Inherits:
Object
  • Object
show all
Defined in:
lib/apia/rack.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, api, namespace, **options) ⇒ Rack

Returns a new instance of Rack.



12
13
14
15
16
17
# File 'lib/apia/rack.rb', line 12

def initialize(app, api, namespace, **options)
  @app = app
  @api = api
  @namespace = '/' + namespace.sub(/\A\/+/, '').sub(/\/+\z/, '')
  @options = options
end

Class Method Details

.error_triplet(code, description: nil, detail: {}, status: 500, headers: {}) ⇒ Array

Return a triplet for a given error using the standard error schema

Parameters:

  • code (String)
  • description (String) (defaults to: nil)
  • detail (Hash) (defaults to: {})
  • status (Integer) (defaults to: 500)
  • headers (Hash) (defaults to: {})

Returns:

  • (Array)


201
202
203
204
205
206
207
208
209
# File 'lib/apia/rack.rb', line 201

def error_triplet(code, description: nil, detail: {}, status: 500, headers: {})
  json_triplet({
                 error: {
                   code: code,
                   description: description,
                   detail: detail
                 }
               }, status: status, headers: headers.merge('x-api-schema' => 'json-error'))
end

.json_triplet(body, status: 200, headers: {}) ⇒ Array

Return a JSON-ready triplet for the given body.

Parameters:

  • body (Hash, Array)
  • status (Integer) (defaults to: 200)
  • headers (Hash) (defaults to: {})

Returns:

  • (Array)


171
172
173
# File 'lib/apia/rack.rb', line 171

def json_triplet(body, status: 200, headers: {})
  response_triplet(body.to_json, content_type: Apia::Response::JSON, status: status, headers: headers)
end

.plain_triplet(body, status: 200, headers: {}) ⇒ Array

Return a plain text triplet for the given body.

Parameters:

  • body (String)
  • status (Integer) (defaults to: 200)
  • headers (Hash) (defaults to: {})

Returns:

  • (Array)


161
162
163
# File 'lib/apia/rack.rb', line 161

def plain_triplet(body, status: 200, headers: {})
  response_triplet(body, content_type: Apia::Response::PLAIN, status: status, headers: headers)
end

.response_triplet(body, content_type:, status: 200, headers: {}) ⇒ Array

Return a triplet for the given body.

Parameters:

  • body (Hash, Array)
  • content_type (String)
  • status (Integer) (defaults to: 200)
  • headers (Hash) (defaults to: {})

Returns:

  • (Array)


182
183
184
185
186
187
188
189
190
191
# File 'lib/apia/rack.rb', line 182

def response_triplet(body, content_type:, status: 200, headers: {})
  content_length = body.bytesize.to_s
  body = [body] unless body.respond_to?(:each)

  [
    status,
    headers.merge('content-type' => content_type, 'content-length' => content_length),
    body
  ]
end

Instance Method Details

#apiApia::API

Return the API object

Returns:



46
47
48
49
50
51
# File 'lib/apia/rack.rb', line 46

def api
  return Object.const_get(@api) if @api.is_a?(String) && development?
  return @cached_api ||= Object.const_get(@api) if @api.is_a?(String)

  @api
end

#call(env) ⇒ Array

Actually make the request

Parameters:

  • env (Hash)

Returns:

  • (Array)

    a rack triplet



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/apia/rack.rb', line 57

def call(env)
  if @options[:hosts]&.none? { |host| host == env['HTTP_HOST'] }
    return @app.call(env)
  end

  unless env['PATH_INFO'] =~ /\A#{Regexp.escape(@namespace)}\/([a-z].*)\z/i
    return @app.call(env)
  end

  api_path = Regexp.last_match(1)

  handle_request(env, api_path)
end

#development?Boolean

Is this supposed to be running in development? This will validate the whole API on each request as well as being more verbose about internal server errors that are encountered.

Returns:

  • (Boolean)


24
25
26
27
28
29
# File 'lib/apia/rack.rb', line 24

def development?
  env_is_dev = ENV['RACK_ENV'] == 'development'
  return true if env_is_dev && @options[:development].nil?

  @options[:development] == true
end

#find_route(method, path) ⇒ nil, Hash

Parse a given full path and return nil if it doesn’t match our namespace or return a hash with the controller and endpoint named as available.

Parameters:

  • path (String)

    /core/v1/controller/endpoint

Returns:

  • (nil, Hash)


37
38
39
40
41
# File 'lib/apia/rack.rb', line 37

def find_route(method, path)
  return if api.nil?

  api.definition.route_set.find(method.to_s.downcase.to_sym, path).first
end