Class: OpenapiFirst::Definition

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/openapi_first/definition.rb

Overview

Represents an OpenAPI API Description document This is returned by OpenapiFirst.load.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(contents, filepath = nil, path_prefix = nil) {|@config| ... } ⇒ Definition

Returns a new instance of Definition.

Parameters:

  • contents (Hash)

    The OpenAPI document.

  • filepath (String) (defaults to: nil)

    The file path of the OpenAPI document.

  • path_prefix (String, nil) (defaults to: nil)

    An optional path prefix, that is not documented, that all requests begin with.

Yields:



26
27
28
29
30
31
32
33
34
35
# File 'lib/openapi_first/definition.rb', line 26

def initialize(contents, filepath = nil, path_prefix = nil)
  @filepath = filepath
  @path_prefix = path_prefix
  @config = OpenapiFirst.configuration.child
  yield @config if block_given?
  @config.freeze
  @router = Builder.build_router(contents, filepath:, config:)
  @resolved = contents
  @paths = @router.routes.map(&:path).to_a.uniq # TODO: Refactor
end

Instance Attribute Details

#configConfiguration (readonly)

Returns:



17
18
19
# File 'lib/openapi_first/definition.rb', line 17

def config
  @config
end

#filepathString? (readonly)

Returns:

  • (String, nil)


13
14
15
# File 'lib/openapi_first/definition.rb', line 13

def filepath
  @filepath
end

#path_prefixString? (readonly)

Returns:

  • (String, nil)


15
16
17
# File 'lib/openapi_first/definition.rb', line 15

def path_prefix
  @path_prefix
end

#pathsEnumerable[String] (readonly)

Returns:

  • (Enumerable[String])


19
20
21
# File 'lib/openapi_first/definition.rb', line 19

def paths
  @paths
end

#routerRouter (readonly)

Returns:



21
22
23
# File 'lib/openapi_first/definition.rb', line 21

def router
  @router
end

Instance Method Details

#[](key) ⇒ Hash

Gives access to the raw resolved Hash. Like ‘mydefinition.dig(’schemas’, ‘Stations’)‘

Returns:

  • (Hash)


40
# File 'lib/openapi_first/definition.rb', line 40

def_delegators :@resolved, :[]

#inspectObject



65
66
67
# File 'lib/openapi_first/definition.rb', line 65

def inspect
  "#<#{self.class.name} @key='#{key}'>"
end

#keyString

Returns a unique identifier for this API definition

Returns:

  • (String)

    A unique key for this API definition



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/openapi_first/definition.rb', line 49

def key
  return filepath if filepath

  info = self['info'] || {}
  title = info['title']
  version = info['version']

  if title.nil? || version.nil?
    raise ArgumentError,
          "Cannot generate key for the OpenAPI document because 'info.title' or 'info.version' is missing. " \
          'Please add these fields to your OpenAPI document.'
  end

  "#{title} @ #{version}"
end

#routesEnumerable[Router::Route]

Returns an Enumerable of available Routes for this API description.

Returns:



45
# File 'lib/openapi_first/definition.rb', line 45

def_delegators :@router, :routes

#validate_request(request, raise_error: false) ⇒ ValidatedRequest

Validates the request against the API description.

Parameters:

  • request (Rack::Request)

    The Rack request object.

  • raise_error (Boolean) (defaults to: false)

    Whether to raise an error if validation fails.

Returns:



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/openapi_first/definition.rb', line 73

def validate_request(request, raise_error: false)
  route = @router.match(request.request_method, resolve_path(request), content_type: request.content_type)
  if route.error
    ValidatedRequest.new(request, error: route.error)
  else
    route.request_definition.validate(request, route_params: route.params)
  end.tap do |validated|
    @config.after_request_validation.each { |hook| hook.call(validated, self) }
    raise validated.error.exception(validated) if validated.error && raise_error
  end
end

#validate_response(request, response, raise_error: false) ⇒ ValidatedResponse

Validates the response against the API description.

Parameters:

  • request (Rack::Request)

    The Rack request object.

  • response (Rack::Response)

    The Rack response object.

  • raise_error (Boolean) (defaults to: false)

    Whether to raise an error if validation fails.

Returns:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/openapi_first/definition.rb', line 90

def validate_response(request, response, raise_error: false)
  route = @router.match(request.request_method, resolve_path(request), content_type: request.content_type)
  return if route.error # Skip response validation for unknown requests

  response_match = route.match_response(status: response.status, content_type: response.content_type)
  error = response_match.error
  validated = if error
                ValidatedResponse.new(response, error:)
              else
                response_match.response.validate(response)
              end
  @config.after_response_validation&.each { |hook| hook.call(validated, request, self) }
  raise validated.error.exception(validated) if raise_error && validated.invalid?

  validated
end