class Committee::SchemaValidator::HyperSchema::ResponseValidator
Attributes
Public Class Methods
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 9 def initialize(link, options = {}) @link = link @validate_success_only = options[:validate_success_only] @allow_blank_structures = options[:allow_blank_structures] @validators = {} if link.is_a? Drivers::OpenAPI2::Link link.target_schemas.each do |status, schema| @validators[status] = JsonSchema::Validator.new(target_schema(link)) end else @validators[link.status_success] = JsonSchema::Validator.new(target_schema(link)) end end
Public Instance Methods
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 24 def call(status, headers, data) unless [204, 304].include?(status) # 204 No Content or 304 Not Modified response = Rack::Response.new(data, status, headers) check_content_type!(response) end # List is a special case; expect data in an array. # # This is poor form that's here so as not to introduce breaking behavior. # The "instances" value of "rel" is a Heroku-ism and was originally # introduced before we understood how to use "targetSchema". It's not # meaningful with the context of the hyper-schema specification and # should be eventually be removed. if legacy_hyper_schema_rel?(@link) if !data.is_a?(Array) raise InvalidResponse, "List endpoints must return an array of objects." end # only consider the first object during the validation from here on # (but only in cases where `targetSchema` is not set) data = data[0] # if the array was empty, allow it through return if data == nil end if allow_blank_structures && @link.is_a?(Committee::Drivers::OpenAPI2::Link) && !@link.target_schema return if data.nil? end begin if Committee::Middleware::ResponseValidation.validate?(status, validate_success_only) raise InvalidResponse, "Invalid response.#{@link.href} status code #{status} definition does not exist" if @validators[status].nil? if !@validators[status].validate(data) errors = JsonSchema::SchemaError.aggregate(@validators[status].errors).join("\n") raise InvalidResponse, "Invalid response.\n\n#{errors}" end end rescue => e raise InvalidResponse, "Invalid response.\n\nschema is undefined" if /undefined method .all_of. for nil/ =~ e.message raise e end end
Private Instance Methods
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 79 def check_content_type!(response) if @link.media_type unless Rack::Mime.match?(response_media_type(response), @link.media_type) raise Committee::InvalidResponse, %{"Content-Type" response header must be set to "#{@link.media_type}".} end end end
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 87 def legacy_hyper_schema_rel?(link) link.is_a?(Committee::Drivers::HyperSchema::Link) && link.rel == "instances" && !link.target_schema end
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 70 def response_media_type(response) if response.respond_to?(:media_type) response.media_type.to_s else # for rack compatibility. In rack v 1.5.0, Rack::Response doesn't have media_type response.content_type.to_s.split(";").first.to_s end end
Source
# File lib/committee/schema_validator/hyper_schema/response_validator.rb, line 97 def target_schema(link) if link.target_schema link.target_schema elsif legacy_hyper_schema_rel?(link) link.parent end end
Gets the target schema of a link. This is normally just the standard response schema, but we allow some legacy behavior for hyper-schema links tagged with rel=instances to instead use the schema of their parent resource.