Class: Alf::Rack::Response

Inherits:
Rack::Response
  • Object
show all
Defined in:
lib/alf/rack/response.rb

Overview

Specialization of ::Rack::Response that automatically handles the encoding of tuples and relations according to HTTP_ACCEPT and available renderers.

Example:

“‘ require ’sinatra’

use Alf::Rack::Connect{|cfg| … }

get ‘/users’ do

# get the connection (see Alf::Rack::Connect)
conn = ...

# The body relation/relvar will automatically be encoded to
# whatever format the user want among the available ones.
# The Content-Type response header is set accordingly.
Alf::Rack::Response.new(env){|r|
  r.body = conn.query{ users }
}.finish

end “‘

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env = {}) ⇒ Response

Prepares a Response instance for a given Rack environment. Raises an AcceptError if no renderer can be found for the HTTP_ACCEPT header.



31
32
33
34
# File 'lib/alf/rack/response.rb', line 31

def initialize(env = {})
  @renderer = Response.renderer!(env)
  super([], 200, 'Content-Type' => @renderer.mime_type)
end

Class Method Details

.accept(env) ⇒ Object

Returns the HTTP_ACCEPT header of env. Defaults to ‘application/json’



61
62
63
# File 'lib/alf/rack/response.rb', line 61

def accept(env)
  env['HTTP_ACCEPT'] || 'application/json'
end

.renderer(env) ⇒ Object

Returns the best renderer to use given HTTP_ACCEPT header and available Alf renderers.



47
48
49
50
51
52
# File 'lib/alf/rack/response.rb', line 47

def renderer(env)
  media_type = ::Rack::Accept::MediaType.new(accept(env))
  if best = media_type.best_of(supported_media_types)
    Renderer.each.find{|(name,_,r)| r.mime_type == best }.last
  end
end

.renderer!(env) ⇒ Object

Returns the renderer to use for env. Raises an AcceptError if no renderer can be found.



56
57
58
# File 'lib/alf/rack/response.rb', line 56

def renderer!(env)
  renderer(env) || raise(AcceptError, "Unsupported content type `#{accept(env)}`")
end

.supported_media_typesObject

Returns media types supported by the Renderer class.



66
67
68
# File 'lib/alf/rack/response.rb', line 66

def supported_media_types
  Renderer.each.map{|(_,_,r)| r.mime_type}.compact.sort
end

Instance Method Details

#body=(payload) ⇒ Object

Sets the body of the response to payload. The latter can be any object that Alf is able to render through the IO renderers (relations, relvars, tuples, etc.).



39
40
41
# File 'lib/alf/rack/response.rb', line 39

def body=(payload)
  super(@renderer.new(payload))
end