class GdsApi::Response
> “/bank-holidays”<br>r.results.web_url
r = Response.new(response, web_urls_relative_to: “www.gov.uk”)
Example:
See: github.com/alphagov/wiki/wiki/API-conventions for details on the API conventions
This is useful on non-canonical frontends, such as those in staging environments.
By specifying a base URI, this will convert all matching web_urls into relative URLs
GOV.UK context. However on internal systems we want to present relative URLs.
API endpoints should return absolute URLs so that they make sense outside of the
Responses can be configured to use relative URLs for ‘web_url` properties.
an object that has the read behaviour of both a Hash and an OpenStruct
This wraps an HTTP response with a JSON body, and presents this as¶ ↑
def self.build_ostruct_recursively(value)
def self.build_ostruct_recursively(value) case value when Hash OpenStruct.new(Hash[value.map { |k, v| [k, build_ostruct_recursively(v)] }]) when Array value.map { |v| build_ostruct_recursively(v) } else value end end
def blank?; false; end
def blank?; false; end
def cache_control
def cache_control @cache_control ||= Rack::Cache::CacheControl.new(headers[:cache_control]) end
def code
def code # Return an integer code for consistency with HTTPErrorResponse @http_response.code end
def expires_at
def expires_at if headers[:date] && cache_control.max_age response_date = Time.parse(headers[:date]) response_date + cache_control.max_age elsif headers[:expires] Time.parse(headers[:expires]) end end
def expires_in
def expires_in return unless headers[:date] age = Time.now.utc - Time.parse(headers[:date]) if cache_control.max_age cache_control.max_age - age.to_i elsif headers[:expires] Time.parse(headers[:expires]).to_i - Time.now.utc.to_i end end
def headers
def headers @http_response.headers end
def initialize(http_response, options = {})
def initialize(http_response, options = {}) @http_response = http_response @web_urls_relative_to = URI.parse(options[:web_urls_relative_to]) if options[:web_urls_relative_to] end
def method_missing(method_sym, *arguments, &block)
def method_missing(method_sym, *arguments, &block) super if GdsApi.config.hash_response_for_requests to_ostruct.public_send(method_sym, *arguments, &block) end
def present?; true; end
def present?; true; end
def raw_response_body
def raw_response_body @http_response.body end
def respond_to_missing?(method, include_private)
def respond_to_missing?(method, include_private) super if GdsApi.config.hash_response_for_requests to_ostruct.respond_to?(method, include_private) end
def to_hash
def to_hash @parsed ||= transform_parsed(JSON.parse(@http_response.body)) end
def to_ostruct
def to_ostruct raise NoMethodError if GdsApi.config.hash_response_for_requests @ostruct ||= self.class.build_ostruct_recursively(to_hash) end
def transform_parsed(value)
def transform_parsed(value) return value if @web_urls_relative_to.nil? case value when Hash Hash[value.map { |k, v| # NOTE: Don't bother transforming if the value is nil if 'web_url' == k && v # Use relative URLs to route when the web_url value is on the # same domain as the site root. Note that we can't just use the # `route_to` method, as this would give us technically correct # but potentially confusing `//host/path` URLs for URLs with the # same scheme but different hosts. relative_url = @web_urls_relative_to.route_to(v) [k, relative_url.host ? v : relative_url.to_s] else [k, transform_parsed(v)] end }] when Array value.map { |v| transform_parsed(v) } else value end end