Module: Rubino::API::Responses

Defined in:
lib/rubino/api/responses.rb

Overview

Coerces Operation return values into Rack response triples. Lets operations return whatever shape is most convenient (a plain Hash for 200, a [status, body] pair for other codes, or a full Rack triple for streaming/binary), while the router always hands Rack a valid triple.

Class Method Summary collapse

Class Method Details

.coerce(value) ⇒ Array(Integer, Hash, Array<String>)

Normalize an operation result. See Router class comment for the contract.

Parameters:

  • value (Hash, Array, #to_rack)

Returns:

  • (Array(Integer, Hash, Array<String>))

    Rack triple

Raises:

  • (ArgumentError)

    when value doesn’t match any supported shape



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rubino/api/responses.rb', line 31

def coerce(value)
  case value
  when Array
    coerce_array(value)
  when Hash
    json(200, value)
  else
    return value.to_rack if value.respond_to?(:to_rack)

    raise ArgumentError, "operation returned unsupported value: #{value.class}"
  end
end

.coerce_array(value) ⇒ Object

Disambiguates [status, body] (length 2, JSON-encoded) from a raw

status, headers, body

Rack triple (length 3, passed through).



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rubino/api/responses.rb', line 46

def coerce_array(value)
  case value.length
  when 2
    status, body = value
    # RFC 7231 §6.3.5: a 204 response MUST NOT have a message body. We
    # force the body to "" regardless of what the operation returned so
    # we never emit `null\n` (a 4-byte JSON literal) for a No Content.
    return [status, {}, [""]] if status == 204

    json(status, body)
  when 3
    value
  else
    raise ArgumentError, "operation returned array of length #{value.length}; expected 2 or 3"
  end
end

.json(status, payload) ⇒ Array(Integer, Hash, Array<String>)

Builds a JSON response triple with content-type set.

Returns:

  • (Array(Integer, Hash, Array<String>))


17
18
19
# File 'lib/rubino/api/responses.rb', line 17

def json(status, payload)
  [status, { "content-type" => "application/json" }, [JSON.generate(payload)]]
end

.no_contentArray(Integer, Hash, Array)

Returns empty 204 response triple.

Returns:

  • (Array(Integer, Hash, Array))

    empty 204 response triple



22
23
24
# File 'lib/rubino/api/responses.rb', line 22

def no_content
  [204, {}, []]
end