Class: Spikard::App
- Inherits:
-
Object
- Object
- Spikard::App
- Includes:
- LifecycleHooks
- Defined in:
- lib/spikard/app.rb
Overview
Collects route metadata so the Rust engine can execute handlers. rubocop:disable Metrics/ClassLength
Constant Summary collapse
- HTTP_METHODS =
%w[GET POST PUT PATCH DELETE OPTIONS HEAD TRACE].freeze
- SUPPORTED_OPTIONS =
%i[request_schema response_schema parameter_schema file_params is_async cors].freeze
Instance Attribute Summary collapse
-
#routes ⇒ Object
readonly
Returns the value of attribute routes.
Instance Method Summary collapse
- #default_handler_name(method, path) ⇒ Object
- #handler_map ⇒ Object
-
#initialize ⇒ App
constructor
A new instance of App.
- #register_route(method, path, handler_name: nil, **options, &block) ⇒ Object
- #route_metadata ⇒ Object
-
#run(config: nil, host: nil, port: nil) ⇒ Object
Run the Spikard server with the given configuration.
-
#sse(path, _handler_name: nil, **_options) { ... } ⇒ Proc
Register a Server-Sent Events endpoint.
-
#sse_producers ⇒ Hash
Get all registered SSE producers.
-
#websocket(path, _handler_name: nil, **_options) { ... } ⇒ Proc
Register a WebSocket endpoint.
-
#websocket_handlers ⇒ Hash
Get all registered WebSocket handlers.
Methods included from LifecycleHooks
#lifecycle_hooks, #on_error, #on_request, #on_response, #pre_handler, #pre_validation
Constructor Details
#initialize ⇒ App
Returns a new instance of App.
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/spikard/app.rb', line 129 def initialize @routes = [] @websocket_handlers = {} @sse_producers = {} @lifecycle_hooks = { on_request: [], pre_validation: [], pre_handler: [], on_response: [], on_error: [] } end |
Instance Attribute Details
#routes ⇒ Object (readonly)
Returns the value of attribute routes.
127 128 129 |
# File 'lib/spikard/app.rb', line 127 def routes @routes end |
Instance Method Details
#default_handler_name(method, path) ⇒ Object
170 171 172 173 174 |
# File 'lib/spikard/app.rb', line 170 def default_handler_name(method, path) normalized_path = path.gsub(/[^a-zA-Z0-9]+/, '_').gsub(/__+/, '_').sub(/^_+|_+$/, '') normalized_path = 'root' if normalized_path.empty? "#{method.to_s.downcase}_#{normalized_path}" end |
#handler_map ⇒ Object
161 162 163 164 165 166 167 168 |
# File 'lib/spikard/app.rb', line 161 def handler_map map = {} @routes.each do |entry| name = entry.[:handler_name] map[name] = entry.handler end map end |
#register_route(method, path, handler_name: nil, **options, &block) ⇒ Object
142 143 144 145 146 147 148 149 |
# File 'lib/spikard/app.rb', line 142 def register_route(method, path, handler_name: nil, **, &block) validate_route_arguments!(block, ) handler_name ||= default_handler_name(method, path) = (method, path, handler_name, ) @routes << RouteEntry.new(, block) block end |
#route_metadata ⇒ Object
157 158 159 |
# File 'lib/spikard/app.rb', line 157 def @routes.map(&:metadata) end |
#run(config: nil, host: nil, port: nil) ⇒ Object
Run the Spikard server with the given configuration
rubocop:disable Metrics/AbcSize, Metrics/MethodLength
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/spikard/app.rb', line 245 def run(config: nil, host: nil, port: nil) require 'json' # Backward compatibility: if host/port are provided directly, create a config if config.nil? && (host || port) config = ServerConfig.new( host: host || '127.0.0.1', port: port || 8000 ) elsif config.nil? config = ServerConfig.new elsif config.is_a?(Hash) config = ServerConfig.new(**config) end # Convert route metadata to JSON routes_json = JSON.generate() # Get handler map handlers = handler_map # Get lifecycle hooks hooks = lifecycle_hooks # Get WebSocket handlers and SSE producers ws_handlers = websocket_handlers sse_prods = sse_producers # Call the Rust extension's run_server function Spikard::Native.run_server(routes_json, handlers, config, hooks, ws_handlers, sse_prods) # Keep Ruby process alive while server runs sleep rescue LoadError => e raise 'Failed to load Spikard extension. ' \ "Build it with: task build:ruby\n#{e.}" end |
#sse(path, _handler_name: nil, **_options) { ... } ⇒ Proc
Register a Server-Sent Events endpoint
203 204 205 206 207 208 |
# File 'lib/spikard/app.rb', line 203 def sse(path, _handler_name: nil, **, &factory) raise ArgumentError, 'block required for SSE producer factory' unless factory @sse_producers[path] = factory factory end |
#sse_producers ⇒ Hash
Get all registered SSE producers
220 221 222 |
# File 'lib/spikard/app.rb', line 220 def sse_producers @sse_producers.dup end |
#websocket(path, _handler_name: nil, **_options) { ... } ⇒ Proc
Register a WebSocket endpoint
186 187 188 189 190 191 |
# File 'lib/spikard/app.rb', line 186 def websocket(path, _handler_name: nil, **, &factory) raise ArgumentError, 'block required for WebSocket handler factory' unless factory @websocket_handlers[path] = factory factory end |
#websocket_handlers ⇒ Hash
Get all registered WebSocket handlers
213 214 215 |
# File 'lib/spikard/app.rb', line 213 def websocket_handlers @websocket_handlers.dup end |