open-core / router
PSR-15 compliant fast Router Middleware based on precompiled searching tree
Requires
- php: >=8.1
- psr/container: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
Requires (Dev)
- nyholm/psr7: ^1.5
- phpunit/phpunit: ^9.1
- relay/relay: ~2.0
Provides
README
PSR-15 compliant fast Router Middleware based on precompiled searching tree.
Features
- PSR-7, PSR-11, PSR-15, PSR-17 compliant.
- Controllers with attribute-based (annotations) routing.
- Passing parsed request body as param to controller method.
- Passing PSR request/response objects to controller method.
- Optional controller method params resolved as URL Query params.
- Params and body type casting according handler method signature.
- Router compile advantages:
- No need to load all controller classes every time.
- Because of pre-compiled tree structure, the complexity of matching algorithm is O(log n) instead of O(n).
- Almost no regex matches.
- Reverse routing.
- Fully configurable data deserialization.
Lifecycle
One-time compilation:
- Looking for all Controller and its method according to routes.
- Executing RouteAnnotations to resolve extra Route attributes.
- Building and caching route tree.
- Building and caching data for reverse routing.
Runtime phase 1 (assumption):
- Creating PSR-7
ServerRequest
object.
Runtime phase 2:
- Resolving Controller, method and attributes for PSR-7
ServerRequest
. - Modifying request by attaching custom attributes and data required to run controller.
Runtime phase 3 (assumption):
- Running other middlewares, which can be enabled/disabled based on PSR-7
ServerRequest
attributes. Example: Authorization or CSFR can be disabled for specific routes.
Runtime phase 4:
- Reading the attributes from PSR-7
ServerRequest
. - Running controller with method resolved on Phase 2.
- If controller returned data in simplified form, wrapping it into final response.
Why there is two middlewares for routing?
The main reason is to use annotations (PHP Attributes) to configure other middlewares using Request attributes.
For example, this allows to set AuthMiddleware
in between, so it could reject request before it will be handled by Controller
.
RouteAnnotations
RouteAnnotations
is kind of syntax sugar. The same effect can be reached by Route
$attributes
parameter.
Because route attributes are resolved before route tree is cache, it should not to be dynamic.
Special handler method arguments
There is ability to pass Request or even parsed body directly to route handler:
- If type of handler method parameter is
ServerRequestInterface
, it will be resolved as raw $request. - If type of handler method parameter is
ResponseInterface
, it will be resolved as new $response. So no need to callResponseFactoryInterface
- If parameter is annotated by
Body
attribute, it will be resolved bybody
property of request. Also it could be parsed as JSON if its type isarray
.
Reverse Router
The route path can be generated by route name and params.