Overview of Routing
Overview of Routing
Hazaar offers a robust and flexible routing system that enables seamless mapping of URLs to controllers and actions. This feature facilitates the creation of clean, intuitive URLs for your application.
Unlike other frameworks, Hazaar provides multiple methods for configuring routes, ensuring flexibility and ease of use. The router can be configured using the application.json file, with options to define routes in a PHP file, JSON file, or using attributes in controller classes. Hazaar also provides multiple automatic routing options, including basic and advanced routing methods.
By providing a variety of routing options, Hazaar allows developers to choose the most suitable method based on their application requirements and preferences.
By default, Hazaar uses the file router and loads routes from route.php. You can switch router types and change the route source file in app.php to suit each environment.
Router Modules
- File: Define routes in a
route.phpfile, ideal for routes not directly tied to a controller. - Basic: The simplest method, requiring no configuration. Controllers and their actions are automatically available as routes.
- Advanced: Similar to the basic method but supports nesting controllers in subdirectories.
- Attribute: Use attributes in controller classes to define routes, also extending the advanced router.
- Annotated: Use annotations in controller classes to define routes, extending the advanced router.
- JSON: Define routes in a JSON file, useful for dynamic route definitions from external configurations.
Warning
While the annotated router is still available and fully functional, it's use is discouraged in favor of the attribute router that provides a more efficient and structured way to define routes using PHP 8 attributes. Annotated routes use PHPDoc comments which require additional parsing and are less efficient.
Configuring the Router
The router configuration is specified in the app.php file under the router section:
<?php
return [
'development' => [
'router' => [
'type' => 'basic',
'controller' => 'main',
'action' => 'index',
]
],
];Tips
Router configuration lives under an environment key (such as development) in app.php. This lets you define different routing setups (and even different route sets) per environment, so make sure your router config matches the active runtime.
The type key determines the router type. Available types include:
file: Define routes in aroute.phpfile.basic: Automatically maps controllers to URLs with no configuration.advanced: Supports nesting controllers in subdirectories.attribute: Define routes using attributes in controller classes.annotated: Define routes using annotations in controller classes.json: Define routes in a JSON configuration file.
The controller and action keys specify the default controller and action to use when no route is matched. Or if the controller is matched but no action is specified then the method defined in the action key will be executed.
Callables
A callable is a PHP callback that can be used to execute a function or method. A callable can be a string (class name), an array (class and method with optional arguments), or a closure.
The target controller and method must return a Hazaar\Controller\Response based object, such as Hazaar\Controller\Response\Json or Hazaar\Controller\Response\View.
Class Method
A class method callable is defined as an array containing the class name and method name:
[ControllerClass::class, 'actionMethod']Warning
The target controller method must be non-static and public and not start with an underscore (_).
Class Method with Arguments
A class method callable with arguments is defined as an array containing the class name, method name, and arguments:
[ControllerClass::class, 'actionMethod', 'arg1', 'arg2']This callable executes the actionMethod method in the ControllerClass class with arg1 and arg2 as arguments. This is useful for passing additional data to the controller method or supplying default values that can be overridden by the URL.
Closure
A closure callable is defined as an anonymous function:
function() {
return new Hazaar\Controller\Response\Json(['message' => 'Hello, World!']);
}Class Strings
A class string callable is defined as a string containing the class name:
'ControllerClass'This callable executes the default method in the ControllerClass class.
'ControllerClass::actionMethod'This callable executes the actionMethod method in the ControllerClass class.
'ControllerClass::actionMethod(arg1, arg2)'Response Types
The response type is determined automatically by the return value of the controller method and is useful for ensuring that the error or exception response is returned in the correct format.
Caution
Avoid using mixed return types as the router will not be able to determine the actual response type and will default to HTML.
Available response types include:
Hazaar\Controller\Response::TYPE_HTML: HTML response. This is the default response type if no other type can be determined.Hazaar\Controller\Response::TYPE_JSON: JSON response.Hazaar\Controller\Response::TYPE_XML: XML response.Hazaar\Controller\Response::TYPE_TEXT: Plain text response.Hazaar\Controller\Response::TYPE_BINARY: Binary response. Used if the response is a file download or other binary data such as a PDF.
Route Parameters
Define route parameters in the URL pattern using curly braces {}. The parameter type can be specified using a colon (:) followed by the type. Such as {int:id} or {string:name}. This is not supported by the basic or advanced routers as they do not support custom routes.
Available types include:
int: Integer.float: Floating-point number.string: String.bool: Boolean.
Values are matched based on the type specified. For example, {int:id} will only match integer values. If the value does not match the specified type, the route will not be matched. The value is then passed to the controller method as an argument of the converted type using the name specified in the URL.
Important
Values are passed as arguments to the controller method by name. So a route of /product/{int:id} would pass the id value to the controller method's $id argument.
public function getProduct(int $id) {
// Retrieve the product with the specified ID
}Example:
Router::get('/product/{int:id}', [API::class, 'getProduct']);[
{
"route": "/product/{int:id}",
"controller": "Application\\Controller\\Product",
"action": "getProduct",
"method": "GET"
}
]#[Route('/product/{int:id}', methods: ['GET'])]
public function getProduct(int $id) {
// Retrieve the product with the specified ID
}/**
* @route("/product/{int:id}", methods={"GET"})
*/
public function getProduct(int $id) {
// Retrieve the product with the specified ID
}Default Values
Default values can be specified for route parameters by providing a default value in the callable. This is useful for providing default values when the parameter is not provided in the URL. The array of default values is passed as the third argument to the callable and can be either a numeric array or an associative array.
If the default values are numeric, they are passed to the controller method in the order they are defined. If the default values are associative, they are passed to the controller method by name.
Numeric Array
Numeric arrays are passed to the controller method in the order they are defined.
Router::get('/product/{int:id}', [API::class, 'getProduct', [1234]]);Associative Array
Associative arrays are passed to the controller method by name.
Router::get('/product/{int:id}', [API::class, 'getProduct', ['id' => 1234]]);Middleware
You can attach middleware to specific routes to handle authentication, authorization, or other logic for individual endpoints. Route middleware is specified using the middleware() chaining method for file routes, or the middleware property for JSON routes. You may use either a middleware class name or an alias (defined in your config).
Example (file route):
Router::get('/admin', [AdminController::class, 'dashboard'])
->middleware('auth'); // 'auth' is an alias defined in configExample (JSON route):
[
{
"route": "/admin",
"controller": "Application\\Controller\\Admin",
"action": "dashboard",
"method": "GET",
"middleware": "auth"
}
]Aliases are mapped to middleware class names in your configuration:
<?php
return [
'middleware' => [
'aliases' => [
'auth' => 'App\\Middleware\\RequireAuth',
],
],
];For more details, see Middleware: Route Middleware.