Class: RubstApi::App
Constant Summary
Constants inherited from APIRouter
RubstApi::APIRouter::HTTP_METHODS
Instance Attribute Summary collapse
-
#dependency_overrides ⇒ Object
readonly
Returns the value of attribute dependency_overrides.
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#docs_url ⇒ Object
readonly
Returns the value of attribute docs_url.
-
#openapi_tags ⇒ Object
readonly
Returns the value of attribute openapi_tags.
-
#openapi_url ⇒ Object
readonly
Returns the value of attribute openapi_url.
-
#openapi_version ⇒ Object
readonly
Returns the value of attribute openapi_version.
-
#redoc_url ⇒ Object
readonly
Returns the value of attribute redoc_url.
-
#servers ⇒ Object
readonly
Returns the value of attribute servers.
-
#title ⇒ Object
readonly
Returns the value of attribute title.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Attributes inherited from APIRouter
#dependencies, #prefix, #routes, #tags
Instance Method Summary collapse
- #add_api_route ⇒ Object
- #add_middleware(middleware_class, **options) ⇒ Object
- #call(env) ⇒ Object
- #exception_handler(exception_class, callable = nil, &block) ⇒ Object
- #execute_route(route, request) ⇒ Object
- #include_router ⇒ Object
-
#initialize(title: "RubstAPI", description: nil, version: "0.1.0", openapi_url: "/openapi.json", docs_url: "/docs", redoc_url: "/redoc", openapi_version: "3.1.0", servers: [], openapi_tags: [], dependencies: [], **router_options) ⇒ App
constructor
A new instance of App.
- #mount(path, application, name: nil) ⇒ Object
- #on_event(event, callable = nil, &block) ⇒ Object
- #openapi ⇒ Object
- #route_request(env) ⇒ Object
- #shutdown ⇒ Object
- #startup ⇒ Object
Methods inherited from APIRouter
Constructor Details
#initialize(title: "RubstAPI", description: nil, version: "0.1.0", openapi_url: "/openapi.json", docs_url: "/docs", redoc_url: "/redoc", openapi_version: "3.1.0", servers: [], openapi_tags: [], dependencies: [], **router_options) ⇒ App
Returns a new instance of App.
8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/rubst_api/app.rb', line 8 def initialize(title: "RubstAPI", description: nil, version: "0.1.0", openapi_url: "/openapi.json", docs_url: "/docs", redoc_url: "/redoc", openapi_version: "3.1.0", servers: [], openapi_tags: [], dependencies: [], **) super(dependencies:, **) @title, @description, @version = title, description, version @openapi_url, @docs_url, @redoc_url, @openapi_version = openapi_url, docs_url, redoc_url, openapi_version @servers, @openapi_tags, @dependency_overrides = servers, , {} @exception_handlers, @user_middleware, @startup_handlers, @shutdown_handlers = {}, [], [], [] @mounts = [] @openapi_schema = nil install_default_handlers end |
Instance Attribute Details
#dependency_overrides ⇒ Object (readonly)
Returns the value of attribute dependency_overrides.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def dependency_overrides @dependency_overrides end |
#description ⇒ Object (readonly)
Returns the value of attribute description.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def description @description end |
#docs_url ⇒ Object (readonly)
Returns the value of attribute docs_url.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def docs_url @docs_url end |
#openapi_tags ⇒ Object (readonly)
Returns the value of attribute openapi_tags.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def @openapi_tags end |
#openapi_url ⇒ Object (readonly)
Returns the value of attribute openapi_url.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def openapi_url @openapi_url end |
#openapi_version ⇒ Object (readonly)
Returns the value of attribute openapi_version.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def openapi_version @openapi_version end |
#redoc_url ⇒ Object (readonly)
Returns the value of attribute redoc_url.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def redoc_url @redoc_url end |
#servers ⇒ Object (readonly)
Returns the value of attribute servers.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def servers @servers end |
#title ⇒ Object (readonly)
Returns the value of attribute title.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def title @title end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
5 6 7 |
# File 'lib/rubst_api/app.rb', line 5 def version @version end |
Instance Method Details
#add_api_route ⇒ Object
97 98 99 100 |
# File 'lib/rubst_api/app.rb', line 97 def add_api_route(...) @openapi_schema = nil super end |
#add_middleware(middleware_class, **options) ⇒ Object
107 108 109 110 111 |
# File 'lib/rubst_api/app.rb', line 107 def add_middleware(middleware_class, **) @user_middleware << [middleware_class, ] @middleware_stack = nil self end |
#call(env) ⇒ Object
21 22 23 24 25 |
# File 'lib/rubst_api/app.rb', line 21 def call(env) build_stack.call(env) rescue StandardError => error handle_exception(error) end |
#exception_handler(exception_class, callable = nil, &block) ⇒ Object
113 114 115 |
# File 'lib/rubst_api/app.rb', line 113 def exception_handler(exception_class, callable = nil, &block) @exception_handlers[exception_class] = callable || block end |
#execute_route(route, request) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rubst_api/app.rb', line 51 def execute_route(route, request) resolver = DependencyResolver.new(request, dependency_overrides) values = {} errors = [] body_parameter_count = route.params.values.count { |value| value.is_a?(Param) && value.location == :body } route.dependencies.each { |dependency| resolver.resolve(dependency) } route.params.each do |name, declaration| if declaration.is_a?(Dependency) values[name] = resolver.resolve(declaration) next end raw = extract_parameter(name, declaration, request, body_parameter_count:) if raw.equal?(UNDEFINED) if declaration.required? errors << { type: "missing", loc: [declaration.location, declaration.name_for(name)], msg: "Field required", input: nil } else values[name] = declaration.default.equal?(UNDEFINED) ? nil : declaration.default end next end begin values[name] = Validator.coerce(raw, declaration.type, declaration.constraints) rescue ValidationError => error errors.concat(error.errors.map { |item| item.merge(loc: [declaration.location, declaration.name_for(name)] + Array(item[:loc])) }) end end raise RequestValidationError.new(errors, body: request.body) unless errors.empty? inject_special_arguments(route.endpoint, values, request) result = invoke(route.endpoint, values) response = prepare_response(result, route) if (injected = values[:response]) response.status_code = injected.status_code if injected.status_code != 200 injected.headers.each { |key, value| response.headers[key] = value } end resolver.close finished = response.finish values[:background_tasks]&.call finished ensure resolver&.close end |
#include_router ⇒ Object
102 103 104 105 |
# File 'lib/rubst_api/app.rb', line 102 def include_router(...) @openapi_schema = nil super end |
#mount(path, application, name: nil) ⇒ Object
125 126 127 128 129 |
# File 'lib/rubst_api/app.rb', line 125 def mount(path, application, name: nil) prefix = path.end_with?("/") ? path.chomp("/") : path @mounts << [prefix, application] application end |
#on_event(event, callable = nil, &block) ⇒ Object
117 118 119 120 |
# File 'lib/rubst_api/app.rb', line 117 def on_event(event, callable = nil, &block) handlers = event.to_sym == :startup ? @startup_handlers : @shutdown_handlers handlers << (callable || block) end |
#openapi ⇒ Object
93 94 95 |
# File 'lib/rubst_api/app.rb', line 93 def openapi @openapi_schema ||= OpenAPI.generate(self) end |
#route_request(env) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rubst_api/app.rb', line 27 def route_request(env) request_path, request_method = env.fetch("PATH_INFO", "/"), env.fetch("REQUEST_METHOD", "GET").upcase if (mounted = @mounts.find { |prefix, _| request_path == prefix || request_path.start_with?("#{prefix}/") }) prefix, application = mounted child_path = request_path.delete_prefix(prefix) child_env = env.merge("SCRIPT_NAME" => "#{env["SCRIPT_NAME"]}#{prefix}", "PATH_INFO" => child_path.empty? ? "/" : child_path) return application.call(child_env) end return JSONResponse.new(openapi).finish if openapi_url && request_path == openapi_url return HTMLResponse.new(swagger_html).finish if docs_url && request_path == docs_url return HTMLResponse.new(redoc_html).finish if redoc_url && request_path == redoc_url path_matches = routes.filter_map { |route| [route, route.match(request_path)] if route.match(request_path) } raise HTTPException.new(status_code: 404) if path_matches.empty? route, captures = path_matches.find { |candidate, _| candidate.allowed?(request_method) } unless route allowed = path_matches.flat_map { |candidate, _| candidate.methods }.uniq.join(", ") raise HTTPException.new(status_code: 405, headers: { "Allow" => allowed }) end request = Request.new(env, path_params: captures) execute_route(route, request) end |
#shutdown ⇒ Object
123 |
# File 'lib/rubst_api/app.rb', line 123 def shutdown = @shutdown_handlers.reverse_each(&:call) |
#startup ⇒ Object
122 |
# File 'lib/rubst_api/app.rb', line 122 def startup = @startup_handlers.each(&:call) |