Class: PatientHttp::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/patient_http/response.rb

Overview

Represents an HTTP response from an async request.

This class encapsulates the response data including status, headers, body, and metadata about the request that generated it.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status:, headers:, body:, duration:, request_id:, url:, http_method:, callback_args: nil, redirects: nil) ⇒ Response

Initialize a Response from an Async::HTTP::Response

Parameters:

  • status (Integer)

    HTTP status code

  • headers (Hash, HttpHeaders)

    response headers

  • body (String, nil)

    response body

  • duration (Float)

    request duration in seconds

  • request_id (String)

    the request ID

  • url (String)

    the request URL

  • http_method (Symbol)

    the HTTP method

  • callback_args (Hash, nil) (defaults to: nil)

    callback arguments (string keys)

  • redirects (Array<String>, nil) (defaults to: nil)

    URLs visited during redirect chain



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/patient_http/response.rb', line 64

def initialize(status:, headers:, body:, duration:, request_id:, url:, http_method:, callback_args: nil, redirects: nil)
  @status = status
  @headers = HttpHeaders.new(headers)

  encoding, encoded_body, charset = Payload.encode(body, @headers["content-type"])
  @payload = Payload.new(encoding, encoded_body, charset) unless body.nil?
  @body = UNDEFINED

  @duration = duration
  @request_id = request_id
  @url = url
  @http_method = http_method
  @callback_args_data = callback_args || {}
  @redirects = redirects || []
end

Instance Attribute Details

#durationFloat (readonly)

Returns request duration in seconds.

Returns:

  • (Float)

    request duration in seconds



19
20
21
# File 'lib/patient_http/response.rb', line 19

def duration
  @duration
end

#headersHttpHeaders (readonly)

Returns response headers.

Returns:



16
17
18
# File 'lib/patient_http/response.rb', line 16

def headers
  @headers
end

#http_methodSymbol (readonly)

Returns HTTP method.

Returns:

  • (Symbol)

    HTTP method



28
29
30
# File 'lib/patient_http/response.rb', line 28

def http_method
  @http_method
end

#redirectsArray<String> (readonly)

Returns URLs visited during redirect chain (empty if no redirects).

Returns:

  • (Array<String>)

    URLs visited during redirect chain (empty if no redirects)



31
32
33
# File 'lib/patient_http/response.rb', line 31

def redirects
  @redirects
end

#request_idString (readonly)

Returns request ID.

Returns:

  • (String)

    request ID



22
23
24
# File 'lib/patient_http/response.rb', line 22

def request_id
  @request_id
end

#statusInteger (readonly)

Returns HTTP status code.

Returns:

  • (Integer)

    HTTP status code



13
14
15
# File 'lib/patient_http/response.rb', line 13

def status
  @status
end

#urlString (readonly)

Returns request URL.

Returns:

  • (String)

    request URL



25
26
27
# File 'lib/patient_http/response.rb', line 25

def url
  @url
end

Class Method Details

.load(hash) ⇒ Response

Reconstruct a Response from a hash

Parameters:

  • hash (Hash)

    hash representation

Returns:



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/patient_http/response.rb', line 38

def load(hash)
  new(
    status: hash["status"],
    headers: hash["headers"],
    body: Payload.load(hash["body"])&.value,
    duration: hash["duration"],
    request_id: hash["request_id"],
    url: hash["url"],
    http_method: hash["http_method"]&.to_sym,
    callback_args: hash["callback_args"],
    redirects: hash["redirects"]
  )
end

Instance Method Details

#as_jsonHash

Serialize to JSON hash.

Returns:

  • (Hash)


161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/patient_http/response.rb', line 161

def as_json
  {
    "status" => status,
    "headers" => headers.to_h,
    "body" => @payload&.as_json,
    "duration" => duration,
    "request_id" => request_id,
    "url" => url,
    "http_method" => http_method.to_s,
    "callback_args" => @callback_args_data,
    "redirects" => @redirects
  }
end

#bodyString?

Returns the response body, decoding it from the payload if necessary.

Returns:

  • (String, nil)

    The decoded response body or nil if there was no body.



90
91
92
93
# File 'lib/patient_http/response.rb', line 90

def body
  @body = @payload&.value if @body.equal?(UNDEFINED)
  @body
end

#callback_argsCallbackArgs

Returns the callback arguments as a CallbackArgs object.

Returns:



83
84
85
# File 'lib/patient_http/response.rb', line 83

def callback_args
  @callback_args ||= CallbackArgs.load(@callback_args_data)
end

#client_error?Boolean

Check if response is a client error (4xx status)

Returns:

  • (Boolean)


112
113
114
# File 'lib/patient_http/response.rb', line 112

def client_error?
  status >= 400 && status < 500
end

#content_typeString?

Get the Content-Type header

Returns:

  • (String, nil)


133
134
135
# File 'lib/patient_http/response.rb', line 133

def content_type
  headers["content-type"]
end

#error?Boolean

Check if response is any error (4xx or 5xx status)

Returns:

  • (Boolean)


126
127
128
# File 'lib/patient_http/response.rb', line 126

def error?
  status >= 400 && status < 600
end

#jsonHash, Array

Parse response body as JSON

Returns:

  • (Hash, Array)

    parsed JSON

Raises:

  • (RuntimeError)

    if Content-Type is not application/json

  • (JSON::ParserError)

    if body is not valid JSON



150
151
152
153
154
155
156
# File 'lib/patient_http/response.rb', line 150

def json
  unless json?
    raise "Response Content-Type is not application/json (got: #{content_type.inspect})"
  end

  JSON.parse(body)
end

#json?Boolean

Return true if Content-Type indicates JSON.

Returns:

  • (Boolean)


140
141
142
143
# File 'lib/patient_http/response.rb', line 140

def json?
  type = content_type.to_s.downcase
  type.match?(%r{\Aapplication/[^ ]*json\b}) || type == "text/json"
end

#redirect?Boolean

Check if response is a redirect (3xx status)

Returns:

  • (Boolean)


105
106
107
# File 'lib/patient_http/response.rb', line 105

def redirect?
  status >= 300 && status < 400
end

#server_error?Boolean

Check if response is a server error (5xx status)

Returns:

  • (Boolean)


119
120
121
# File 'lib/patient_http/response.rb', line 119

def server_error?
  status >= 500 && status < 600
end

#success?Boolean

Check if response is successful (2xx status)

Returns:

  • (Boolean)


98
99
100
# File 'lib/patient_http/response.rb', line 98

def success?
  status >= 200 && status < 300
end

#to_json(options = nil) ⇒ String

Serialize to JSON string.

Parameters:

  • options (Hash) (defaults to: nil)

    options to pass to JSON.generate (for ActiveSupport compatibility)

Returns:

  • (String)

    JSON representation



179
180
181
# File 'lib/patient_http/response.rb', line 179

def to_json(options = nil)
  JSON.generate(as_json, options)
end