VOOZH about

URL: https://deepwiki.com/hypervel/http/4-middleware-and-routing

⇱ Middleware & Routing | hypervel/http | DeepWiki


Loading...
Menu

Middleware & Routing

Purpose and Scope

This document covers the middleware pipeline and routing system in the Hypervel HTTP package. It explains how incoming requests are dispatched to controller actions or closures, how route parameters and dependencies are resolved and injected, and how controller responses are transformed into standardized HTTP responses.

The middleware system consists of three primary components: CoreMiddleware for request dispatching and response transformation, RouteDependency for dependency injection and parameter resolution, and DispatchedRoute for representing matched routes. For information about specific middleware implementations (CORS, validation), see CORS Middleware and Request Validation Middleware. For details on the core middleware's lifecycle management, see Core Middleware & Request Lifecycle.


Architecture Overview

The Hypervel HTTP routing system integrates with Hyperf's routing infrastructure and the FastRoute library to provide route matching, dependency injection, and automatic response transformation.

Component Relationships


Sources: src/CoreMiddleware.php1-203 src/RouteDependency.php1-176 src/DispatchedRoute.php1-108


Request Processing Flow

The following diagram shows how a request flows through the routing system from initial dispatch to final response.


Sources: src/CoreMiddleware.php158-180 src/CoreMiddleware.php111-120 src/CoreMiddleware.php127-152


CoreMiddleware

The CoreMiddleware class implements CoreMiddlewareInterface and serves as the central orchestrator for request dispatching and response handling.

Initialization and Dependencies

The CoreMiddleware constructor receives a ContainerInterface and server name, then initializes two critical dependencies:

DependencyTypePurpose
$dispatcherFastRoute\DispatcherPerforms route pattern matching against request path
$routeDependencyRouteDependencyResolves and injects controller/closure parameters

Sources: src/CoreMiddleware.php40-46

Route Dispatching

The dispatch() method matches the incoming request against registered routes:


The dispatcher returns one of three status codes:

Status CodeConstantMeaning
0Dispatcher::NOT_FOUNDNo route matches the request path
1Dispatcher::FOUNDRoute found with matching HTTP method
2Dispatcher::METHOD_NOT_ALLOWEDRoute exists but HTTP method not allowed

Sources: src/CoreMiddleware.php111-120 src/CoreMiddleware.php168-173

Request Processing

The process() method implements the PSR-15 RequestHandlerInterface and coordinates the entire request handling flow:

  1. Retrieves the DispatchedRoute from request attributes
  2. Dispatches based on route status using a match expression
  3. Transforms non-standard responses to ResponsePlusInterface
  4. Adds the "Server: Hypervel" header to all responses

Sources: src/CoreMiddleware.php158-180

Route Handler Invocation

When a route is found (Dispatcher::FOUND), the handleFound() method invokes the appropriate handler:

Closure Routes

For closure-based routes:

  1. Calls RouteDependency::getClosureParameters() to resolve dependencies
  2. Fires after-resolving callbacks if registered
  3. Invokes the closure with resolved parameters: ($route->getCallback())(...$parameters)

Controller Routes

For controller action routes:

  1. Extracts controller class and action method: [$controller, $action] = $route->getControllerCallback()
  2. Retrieves controller instance from DI container: $this->container->get($controller)
  3. Validates that the action method exists
  4. Calls RouteDependency::getMethodParameters() to resolve dependencies
  5. Fires after-resolving callbacks if registered
  6. Invokes the action, checking for callAction() method first for custom invocation logic

Sources: src/CoreMiddleware.php127-152


Response Transformation

The transferToResponse() method converts various return types from controllers/closures into standardized PSR-7 responses. This enables controllers to return simple values without manually constructing response objects.

Supported Response Types















































Return TypeContent-TypeProcessing
Renderable (views)From RenderInterface::getContentType()Calls render() method
stringtext/plainDirect string output
ResponseInterfacePreservedWrapped in ResponsePlusProxy
array or Arrayableapplication/jsonEncoded via Json::encode()
Jsonableapplication/jsonCast to string
Other (with Content-Type set)PreservedCast to string
Other (no Content-Type)text/plainCast to string

Sources: src/CoreMiddleware.php48-95


Dependency Injection with RouteDependency

The RouteDependency class provides sophisticated parameter resolution for route handlers, supporting type-hinted dependencies, route parameters, and default values.

Parameter Resolution Strategy

When resolving parameters for a controller method or closure, the system follows this priority order:


Sources: src/RouteDependency.php156-175

Method and Closure Analysis

The RouteDependency class maintains caches of analyzed method and closure signatures to avoid repeated reflection:

MethodPurposeCache Key Format
getMethodDefinitions()Analyzes controller method parameters"ControllerClass::methodName"
getClosureDefinitions()Analyzes closure parametersspl_object_hash($closure)
getMethodParameters()Resolves method dependenciesUses getMethodDefinitions() + route arguments
getClosureParameters()Resolves closure dependenciesUses getClosureDefinitions() + route arguments

The resolved definitions are stored in $resolvedDefinitions array to prevent redundant reflection operations.

Sources: src/RouteDependency.php108-151

After-Resolving Callbacks

The RouteDependency class supports registering callbacks that fire after dependencies are resolved but before the route handler is invoked. This enables cross-cutting concerns like logging, authorization, or state initialization.

Registration


The afterResolving() method validates that the class exists and stores callbacks in $afterResolvingCallbacks array, indexed by class name.

Callback Execution

The fireAfterResolvingCallbacks() method iterates through resolved dependencies and invokes applicable callbacks:

  1. Skips non-object dependencies
  2. Calls getAfterResolvingCallbacks() to find callbacks matching the dependency's type
  3. Invokes each callback with the dependency instance and DispatchedRoute

The getAfterResolvingCallbacks() method uses instanceof checks to support callbacks registered for parent classes and interfaces, with results cached in $resolvedCallbacks.

Sources: src/RouteDependency.php48-101

Dependencies

The RouteDependency constructor requires four dependencies from the DI container:

DependencyInterfacePurpose
$containerContainerInterfaceResolves type-hinted dependencies
$normalizerNormalizerInterfaceConverts route parameters to target types
$methodDefinitionCollectorMethodDefinitionCollectorInterfaceProvides method parameter metadata
$closureDefinitionCollectorClosureDefinitionCollectorInterfaceProvides closure parameter metadata

Sources: src/RouteDependency.php40-46


DispatchedRoute

The DispatchedRoute class extends Hyperf's Dispatched class with additional methods for accessing route information.

Route Information Access


Method Categories

The DispatchedRoute methods can be grouped into four functional categories:

Handler Type Detection

  • isClosure(): Returns true if the route handler is a closure
  • isControllerAction(): Returns true if the route handler is a controller action

Handler Access

  • getHandler(): Returns the underlying RouteHandler instance
  • getCallback(): Returns the callable (closure or controller string)
  • getControllerClass(): Returns the controller class name for controller actions
  • getControllerCallback(): Returns [controller, action] array for controller actions

Parameter Access

  • parameters(): Returns all route parameters as an array
  • parameter($key, $default): Gets a specific parameter with optional default
  • hasParameters(): Checks if any parameters exist
  • hasParameter($name): Checks if a specific parameter exists

Metadata Access

  • getName(): Returns the route name if assigned
  • getMiddleware(): Returns the route-specific middleware array

Sources: src/DispatchedRoute.php1-108


Error Handling

The CoreMiddleware handles routing errors by throwing specialized HTTP exceptions.

Not Found (404)

The handleNotFound() method is called when Dispatcher::NOT_FOUND status is returned. It simply throws a NotFoundHttpException, which is typically caught by exception handling middleware to render a 404 response.

Sources: src/CoreMiddleware.php185-188

Method Not Allowed (405)

The handleMethodNotAllowed() method is called when a route exists but the HTTP method doesn't match. It receives an array of allowed methods for the route.

OPTIONS Request Handling

For OPTIONS requests (typically CORS preflight), the method returns a response with an Allow header listing the permitted methods, without throwing an exception.

Other Methods

For non-OPTIONS requests, it throws a MethodNotAllowedHttpException with a message containing the allowed methods: "Allow: GET, POST, PUT".

Sources: src/CoreMiddleware.php193-202

Validation Errors

When invoking a controller action, if the method doesn't exist on the controller instance, a ServerErrorHttpException is thrown with a descriptive message: "{$controller}@{$action} does not exist."

Sources: src/CoreMiddleware.php139-141


Integration Points

The middleware and routing system integrates with several framework components:

FastRoute Integration

The CoreMiddleware::createDispatcher() method obtains a FastRoute\Dispatcher instance from Hyperf's DispatcherFactory, configured for the specific server name:

Sources: src/CoreMiddleware.php105-109

Context Management

The routing system uses two context systems:

  • RequestContext::set(): Stores the current request for access throughout the application
  • ResponseContext::get(): Retrieves the current response instance for manipulation

The CoreMiddleware::response() method demonstrates context-based response access.

Sources: src/CoreMiddleware.php100-103 src/CoreMiddleware.php118-119 src/CoreMiddleware.php160

View System Integration

When transforming Renderable responses, if the response is a ViewInterface and view events are enabled in configuration, the CoreMiddleware dispatches a ViewRendered event:

Sources: src/CoreMiddleware.php55-61