class Grape::Middleware::Versioner::Header
This middleware sets various version related rack environment variables based on the HTTP Accept header with the pattern: application/vnd.:vendor-:version+:format
Example: For request header
Accept: application/vnd.mycompany.a-cool-resource-v1+json
The following rack env variables are set:
env['api.type'] => 'application' env['api.subtype'] => 'vnd.mycompany.a-cool-resource-v1+json' env['api.vendor] => 'mycompany.a-cool-resource' env['api.version] => 'v1' env['api.format] => 'json'
If version does not match this route, then a 406 is raised with X-Cascade header to alert Grape::Router
to attempt the next matched route.
Public Instance Methods
before()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 27 def before match_best_quality_media_type! do |media_type| env.update( Grape::Env::API_TYPE => media_type.type, Grape::Env::API_SUBTYPE => media_type.subtype, Grape::Env::API_VENDOR => media_type.vendor, Grape::Env::API_VERSION => media_type.version, Grape::Env::API_FORMAT => media_type.format ) end end
Private Instance Methods
accept_header()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 57 def accept_header env[Grape::Http::Headers::HTTP_ACCEPT] end
accept_header_check!()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 68 def accept_header_check! return if accept_header.present? invalid_accept_header!('Accept header must be set.') end
allowed_methods()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 53 def allowed_methods env[Grape::Env::GRAPE_ALLOWED_METHODS] end
available_media_types()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 115 def available_media_types [].tap do |available_media_types| base_media_type = "application/vnd.#{vendor}" content_types.each_key do |extension| versions&.reverse_each do |version| available_media_types << "#{base_media_type}-#{version}+#{extension}" available_media_types << "#{base_media_type}-#{version}" end available_media_types << "#{base_media_type}+#{extension}" end available_media_types << base_media_type available_media_types.concat(content_types.values.flatten) end end
fail!(grape_allowed_methods)
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 96 def fail!(grape_allowed_methods) return grape_allowed_methods if grape_allowed_methods.present? media_types = q_values_mime_types.map { |mime_type| Grape::Util::MediaType.parse(mime_type) } vendor_not_found!(media_types) || version_not_found!(media_types) end
invalid_accept_header!(message)
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 88 def invalid_accept_header!(message) raise Grape::Exceptions::InvalidAcceptHeader.new(message, error_headers) end
invalid_version_header!(message)
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 92 def invalid_version_header!(message) raise Grape::Exceptions::InvalidVersionHeader.new(message, error_headers) end
match_best_quality_media_type!() { |media_type| ... }
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 41 def match_best_quality_media_type! return unless vendor strict_header_checks! media_type = Grape::Util::MediaType.best_quality(accept_header, available_media_types) if media_type yield media_type else fail!(allowed_methods) end end
q_values_mime_types()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 80 def q_values_mime_types @q_values_mime_types ||= Rack::Utils.q_values(accept_header).map(&:first) end
strict_header_checks!()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 61 def strict_header_checks! return unless strict? accept_header_check! version_and_vendor_check! end
vendor_not_found!(media_types)
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 103 def vendor_not_found!(media_types) return unless media_types.all? { |media_type| media_type&.vendor && media_type.vendor != vendor } invalid_accept_header!('API vendor not found.') end
version_and_vendor?()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 84 def version_and_vendor? q_values_mime_types.any? { |mime_type| Grape::Util::MediaType.match?(mime_type) } end
version_and_vendor_check!()
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 74 def version_and_vendor_check! return if versions.blank? || version_and_vendor? invalid_accept_header!('API vendor or version not found.') end
version_not_found!(media_types)
click to toggle source
# File lib/grape/middleware/versioner/header.rb, line 109 def version_not_found!(media_types) return unless media_types.all? { |media_type| media_type&.version && versions&.exclude?(media_type.version) } invalid_version_header!('API version not found.') end