Json
Json
JSON Router.
class Json extends \Hazaar\Application\Router\LoaderExtends: Hazaar\Application\Router\Loader
The JSON router is a simple router that reads routes from a JSON file. The JSON file should contain an array of route objects. Each route object should contain the following
- route: The route path to match. This can contain placeholders for arguments. For example, /user/{id} would match /user/123 and /user/abc. The matched values are passed as arguments to the action.
- regex: A regular expression to match the route path. This can be used instead of the route key.
- controller: The controller to use for the route. If not specified, the default controller is used.
- action: The action to use for the route. If not specified, the default action is used.
- args: An array of additional arguments to pass to the action.
- cache: If true, the action result will be cached. The cache key is the controller and action name with the arguments appended. The cache TTL is specified in the ttl key.
- ttl: The time-to-live for the cache.
- method: The HTTP method(s) to match, as a single string (for example "GET"). If not specified, the route defaults to GET.
- methods: The HTTP method(s) to match, as an array (for example ["GET", "POST"]). Takes precedence over
methodwhen both are present.
Example JSON route file:
{
"production": {
"routes": [
{
"route": "/user/{id}",
"controller": "user",
"action": "view"
},
{
"regex": "/user/([0-9]+)",
"controller": "user",
"action": "view"
},
{
"route": "/user/{id}/edit",
"controller": "user",
"action": "edit"
}
]
}
}Like configs/app.php, this file is loaded through Hazaar\Application\Config, which is always resolved for a specific environment (the active APPLICATION_ENV, defaulting to development) — so its routes array must be nested under a matching top-level environment key ("include": "production" works here too, the same as in app.php), not given as a bare top-level array.
In the above example, the first route will match /user/123 and /user/abc and pass the matched value as an argument to the view action of the user controller. The second route will match /user/123 and pass the matched value as an argument to the view action of the user controller. The third route will match /user/123/edit and pass 123 as an argument to the edit action of the user controller.
Properties
loaded
Guards Hazaar\Application\Router\Loader\Json::registerRoutes so the JSON route file is only ever parsed and
private bool $loadedType: bool
registered once per router instance, rather than once per incoming request.
Methods
evaluateRequest
Evaluates the request and sets the controller, action, and arguments based on the request path.
public evaluateRequest(Request $request): ?RouteReturns: Hazaar\Application\Route
Parameters
| Parameter | Type | Description |
|---|---|---|
$request | Hazaar\Application\Request |
getRoutes
Returns every route declared in the JSON route file, registering them on the router first
public getRoutes(): arrayReturns: array
(once) if that hasn't happened yet.
registerRoutes
Parses the configured JSON route file and registers each entry on the router.
private registerRoutes(): voidReturns: void
Guarded by Hazaar\Application\Router\Loader\Json::loaded — without it, every route in the file was previously re-registered on every single incoming request (since Hazaar\Application\Router\Loader\Json::evaluateRequest runs per request), silently growing the router's in-memory route table without bound on a long-lived worker.
Also fixes two bugs found while adding this: (1) Config::open()'s Iterator yields the file's top-level keys, so iterating it directly yielded one $routeItem — the whole routes array itself, keyed 'routes' — rather than the individual route entries this class's own docblock documents, meaning isset($routeItem['route']) was always false and no route was ever registered from a file in that documented shape; and (2) Router::match() (the static facade used to register each entry) resolves a global Application/Router instance via Router::getInstance(), which doesn't exist when this loader is driven outside a live request (e.g. from the OpenAPI generator) — registering through $this->router directly, as below, works in both contexts.
Generated by Hazaar API Doc Generator on Fri, 04 Sep 2026 23:32:17 +0000