Class: OpenapiFirst::Router
- Inherits:
-
Object
- Object
- OpenapiFirst::Router
- Defined in:
- lib/openapi_first/router.rb,
lib/openapi_first/router/find_content.rb,
lib/openapi_first/router/find_response.rb,
lib/openapi_first/router/path_template.rb
Overview
Router can map requests / responses to their API definition
Constant Summary collapse
- RequestMatch =
Returned by #match
Data.define(:request_definition, :params, :error, :responses) do def match_response(status:, content_type:) FindResponse.call(responses, status, content_type, request_method: request_definition.request_method, path: request_definition.path) end end
- Route =
Returned by #routes to introspect all routes
Data.define(:path, :request_method, :requests, :responses)
Instance Method Summary collapse
-
#add_request(request, request_method:, path:, content_type: nil, allow_empty_content: false) ⇒ Object
Add a request definition.
-
#add_response(response, request_method:, path:, status:, response_content_type: nil) ⇒ Object
Add a response definition.
-
#initialize ⇒ Router
constructor
A new instance of Router.
-
#match(request_method, path, content_type: nil) ⇒ Object
Return all request objects that match the given path and request method.
-
#routes ⇒ Object
Returns an enumerator of all routes.
Constructor Details
#initialize ⇒ Router
Returns a new instance of Router.
24 25 26 27 |
# File 'lib/openapi_first/router.rb', line 24 def initialize @static = {} @dynamic = {} # TODO: use a trie or similar end |
Instance Method Details
#add_request(request, request_method:, path:, content_type: nil, allow_empty_content: false) ⇒ Object
Add a request definition
42 43 44 45 46 47 |
# File 'lib/openapi_first/router.rb', line 42 def add_request(request, request_method:, path:, content_type: nil, allow_empty_content: false) route = route_at(path, request_method) requests = route[:requests] requests[content_type] = request requests[nil] = request if allow_empty_content end |
#add_response(response, request_method:, path:, status:, response_content_type: nil) ⇒ Object
Add a response definition
50 51 52 |
# File 'lib/openapi_first/router.rb', line 50 def add_response(response, request_method:, path:, status:, response_content_type: nil) (route_at(path, request_method)[:responses][status] ||= {})[response_content_type] = response end |
#match(request_method, path, content_type: nil) ⇒ Object
Return all request objects that match the given path and request method
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/openapi_first/router.rb', line 55 def match(request_method, path, content_type: nil) path_item, params = find_path_item(path) unless path_item = "Request path #{path} is not defined in API description." return NOT_FOUND.with(error: Failure.new(:not_found, message:)) end contents = path_item.dig(request_method, :requests) return NOT_FOUND.with(error: Failure.new(:method_not_allowed)) unless contents request_definition = FindContent.call(contents, content_type) unless request_definition = "#{content_type_err(content_type)} Content-Type should be #{contents.keys.join(' or ')}." return NOT_FOUND.with(error: Failure.new(:unsupported_media_type, message:)) end responses = path_item.dig(request_method, :responses) RequestMatch.new(request_definition:, params:, error: nil, responses:) end |
#routes ⇒ Object
Returns an enumerator of all routes
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/openapi_first/router.rb', line 30 def routes @static.chain(@dynamic).lazy.flat_map do |path, request_methods| request_methods.filter_map do |request_method, content| next if request_method == :template Route.new(path:, request_method:, requests: content[:requests].each_value.lazy.uniq, responses: content[:responses].each_value.lazy.flat_map(&:values)) end end end |