Module: Tina4::Router
- Defined in:
- lib/tina4/router.rb
Defined Under Namespace
Classes: GroupContext
Class Method Summary collapse
- .add(method, path, handler, auth_handler: nil, swagger_meta: {}, middleware: [], template: nil) ⇒ Object
- .any(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
- .clear! ⇒ Object (also: clear)
- .delete(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
- .find_route(method, path) ⇒ Object
-
.find_ws_route(path) ⇒ Object
Find a matching WebSocket route for a given path.
-
.get(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
Convenience registration methods.
- .get_routes ⇒ Object
-
.get_web_socket_routes ⇒ Object
Parity alias — returns all registered WebSocket routes.
- .group(prefix, auth_handler: nil, middleware: [], &block) ⇒ Object
- .list_routes ⇒ Object
-
.load_routes(directory) ⇒ Object
Load route files from a directory (file-based route discovery).
-
.match(method, path) ⇒ Object
Find a route matching method + path.
-
.method_index ⇒ Object
Routes indexed by HTTP method for O(1) method lookup.
- .patch(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
- .post(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
- .put(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
- .routes ⇒ Object
-
.use(klass) ⇒ Object
Register a class-based middleware globally.
-
.websocket(path, &block) ⇒ Object
Register a WebSocket route.
-
.ws_routes ⇒ Object
Registered WebSocket routes.
Class Method Details
.add(method, path, handler, auth_handler: nil, swagger_meta: {}, middleware: [], template: nil) ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/tina4/router.rb', line 262 def add(method, path, handler, auth_handler: nil, swagger_meta: {}, middleware: [], template: nil) route = Route.new(method, path, handler, auth_handler: auth_handler, swagger_meta: , middleware: middleware, template: template) routes << route method_index[route.method] << route Tina4::Log.debug("Route registered: #{method.upcase} #{path}") route end |
.any(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
294 295 296 |
# File 'lib/tina4/router.rb', line 294 def any(path, middleware: [], swagger_meta: {}, template: nil, &block) add("ANY", path, block, middleware: middleware, swagger_meta: , template: template) end |
.clear! ⇒ Object Also known as: clear
336 337 338 339 340 |
# File 'lib/tina4/router.rb', line 336 def clear! @routes = [] @method_index = Hash.new { |h, k| h[k] = [] } @ws_routes = [] end |
.delete(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
290 291 292 |
# File 'lib/tina4/router.rb', line 290 def delete(path, middleware: [], swagger_meta: {}, template: nil, &block) add("DELETE", path, block, middleware: middleware, swagger_meta: , template: template) end |
.find_route(method, path) ⇒ Object
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/tina4/router.rb', line 298 def find_route(method, path) normalized_method = method.upcase # Normalize path once (not per-route) normalized_path = path.gsub("\\", "/") normalized_path = "/#{normalized_path}" unless normalized_path.start_with?("/") normalized_path = normalized_path.chomp("/") unless normalized_path == "/" # Check ANY routes first, then method-specific routes candidates = (method_index["ANY"] || []) + (method_index[normalized_method] || []) candidates.each do |route| params = route.match_path(normalized_path) return [route, params] if params end nil end |
.find_ws_route(path) ⇒ Object
Find a matching WebSocket route for a given path. Returns [ws_route, params] or nil.
245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/tina4/router.rb', line 245 def find_ws_route(path) normalized = path.gsub("\\", "/") normalized = "/#{normalized}" unless normalized.start_with?("/") normalized = normalized.chomp("/") unless normalized == "/" ws_routes.each do |ws_route| params = ws_route.match?(normalized) return [ws_route, params] if params end nil end |
.get(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
Convenience registration methods
274 275 276 |
# File 'lib/tina4/router.rb', line 274 def get(path, middleware: [], swagger_meta: {}, template: nil, &block) add("GET", path, block, middleware: middleware, swagger_meta: , template: template) end |
.get_routes ⇒ Object
213 214 215 |
# File 'lib/tina4/router.rb', line 213 def get_routes routes end |
.get_web_socket_routes ⇒ Object
Parity alias — returns all registered WebSocket routes.
227 228 229 |
# File 'lib/tina4/router.rb', line 227 def get_web_socket_routes ws_routes end |
.group(prefix, auth_handler: nil, middleware: [], &block) ⇒ Object
343 344 345 |
# File 'lib/tina4/router.rb', line 343 def group(prefix, auth_handler: nil, middleware: [], &block) GroupContext.new(prefix, auth_handler, middleware).instance_eval(&block) end |
.list_routes ⇒ Object
217 218 219 |
# File 'lib/tina4/router.rb', line 217 def list_routes routes end |
.load_routes(directory) ⇒ Object
Load route files from a directory (file-based route discovery)
348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/tina4/router.rb', line 348 def load_routes(directory) return unless Dir.exist?(directory) Dir.glob(File.join(directory, "**/*.rb")).sort.each do |file| begin load file Tina4::Log.debug("Route loaded: #{file}") rescue => e Tina4::Log.error("Failed to load route #{file}: #{e.}") end end end |
.match(method, path) ⇒ Object
Find a route matching method + path. Returns [route, params] or nil. match(method, path) — consistent with Python, PHP, and Node.
316 317 318 |
# File 'lib/tina4/router.rb', line 316 def match(method, path) find_route(method, path) end |
.method_index ⇒ Object
Routes indexed by HTTP method for O(1) method lookup
258 259 260 |
# File 'lib/tina4/router.rb', line 258 def method_index @method_index ||= Hash.new { |h, k| h[k] = [] } end |
.patch(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
286 287 288 |
# File 'lib/tina4/router.rb', line 286 def patch(path, middleware: [], swagger_meta: {}, template: nil, &block) add("PATCH", path, block, middleware: middleware, swagger_meta: , template: template) end |
.post(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
278 279 280 |
# File 'lib/tina4/router.rb', line 278 def post(path, middleware: [], swagger_meta: {}, template: nil, &block) add("POST", path, block, middleware: middleware, swagger_meta: , template: template) end |
.put(path, middleware: [], swagger_meta: {}, template: nil, &block) ⇒ Object
282 283 284 |
# File 'lib/tina4/router.rb', line 282 def put(path, middleware: [], swagger_meta: {}, template: nil, &block) add("PUT", path, block, middleware: middleware, swagger_meta: , template: template) end |
.routes ⇒ Object
209 210 211 |
# File 'lib/tina4/router.rb', line 209 def routes @routes ||= [] end |
.use(klass) ⇒ Object
Register a class-based middleware globally. The class should define static before_* and/or after_* methods. Example:
class AuthMiddleware
def self.before_auth(request, response)
unless request.headers["authorization"]
return [request, response.json({ error: "Unauthorized" }, 401)]
end
[request, response]
end
end
Tina4::Router.use(AuthMiddleware)
332 333 334 |
# File 'lib/tina4/router.rb', line 332 def use(klass) Tina4::Middleware.use(klass) end |
.websocket(path, &block) ⇒ Object
Register a WebSocket route. The handler block receives (connection, event, data) where:
connection — WebSocketConnection with #send, #broadcast, #close, #params
event — :open, :message, or :close
data — String payload for :message, nil for :open/:close
236 237 238 239 240 241 |
# File 'lib/tina4/router.rb', line 236 def websocket(path, &block) ws_route = WebSocketRoute.new(path, block) ws_routes << ws_route Tina4::Log.debug("WebSocket route registered: #{path}") ws_route end |
.ws_routes ⇒ Object
Registered WebSocket routes
222 223 224 |
# File 'lib/tina4/router.rb', line 222 def ws_routes @ws_routes ||= [] end |