open-core/router

PSR-15 compliant fast Router Middleware based on precompiled searching tree

1.0.1 2023-04-15 11:19 UTC

This package is auto-updated.

Last update: 2024-04-12 00:08:49 UTC


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 call ResponseFactoryInterface
  • If parameter is annotated by Body attribute, it will be resolved by body property of request. Also it could be parsed as JSON if its type is array.

Reverse Router

The route path can be generated by route name and params.