LENKRAD - The modern PHP core
Basics
Advanced
Deployment

Routing

Routing of endpoints can be handled by attribute or declaration. This page will explain both.

The Route class

Like most core-classes, Route is used statically while maintaining a single instance of itself. It's responsible for registering routes.

Main methods

Method
Description

Route::get

Registers a GET request

Route::post

Registers a POST request

Route::put

Registers a PUT request

Route::patch

Registers a PATCH request

Route::delete

Registers a DELETE request

Route::request

Registers other/custom requests

With the exception of Route::request, these methods all take the same arguments. LENKRAD intends to work with your IDE and tries to reduce string usage by the user. For these methods, this means that classnames are provided to a route. A class must fulfill the following requirements:

  • Implements Neoan\Routing\Interfaces\Routable
  • Has __invoke method
  • Returns a serializable result, a Model, a Collection or a DataNormalization instance

Example or a routable class


            ?php
            namespace App;

            use Neoan\Routing\Interfaces\Routable;

            class Controller implements Routable
            {
                public function __invoke(): array
                {
                    return ['test' => 'message'];
                }
            }
        

Example of a route using Controller.php


            namespace App;

            use Neoan\Routing\Route;

            Route::get('/test', Controller::class);
        

Middleware Chaining

A route definition can chain routable classes as needed:


            namespace App;

            use Neoan\Routing\Route;

            Route::get('/test', Auth::class, ReadUserFile::class, Controller::class);
        

This will execute one class after another. For a better understanding on how to utilize this feature, please refer to the Middleware chapter of this documentation

Route parameter

In both API & SSR routes, variable parameters are a common necessity. Like many other frameworks in various languages, LENKRAD solves this by markup:


            namespace App;

            use Neoan\Routing\Route;

            // Route will respond to /test/{anything}
            Route::get('/test/:name', Controller::class);

            // Route will respond to /test and /test/{anything}
            Route::get('/test/:name*', Controller::class);

            // Multiple parameters are possible
            Route::get('/test/:name/:id*', Controller::class);
        

Variable usage

Routes using parameters provide their content to Request. To indicate a part of the route as parameter, prefix it with : (colon). To indicate a part of the route is an optional parameter, additionally append it with * (asterisks)

Careful when chaining parameters. It's a common trap to pollute namespaces.

Direct Injection

In very simple projects or routes, the necessity for logic might be overkill. You can therefore directly pass values to the response instead of using a class.


            namespace App;

            use Neoan\Routing\Route;
            use Neoan\Request\Request;

            Route::get('/test/:name')
                ->inject(Request::getParameters());
        
Note that without additional changes to defaults, this only works for the standard JSON response.

Custom response handling

We speak of an either/or when talking about responses. However, in reality you might have different response requirements for a particular route. This is why it's possible to overwrite the default behavior per route.


            namespace App;

            use Neoan\Routing\Route;
            use Neoan\Response\Response;


            // using the default response handler, but overwriting its current default handling
            Route::get('/test', Controller::class)
                ->view('templates/test.html')
                ->response([Response::class,'html']);

            // using your own response handler and its method "answer"
            Route::get('/test', Controller::class)
                ->response([MyResponseHandler::class,'answer']);
        
Response handling is further explained in Response

Attribute Routing

Ever since Ruby on Rails exploded onto the world, annotational routing took the developer's interest. In LENKRAD, you can achieve this with attributes on the class-level.

Setup

In order to make use of this convenient way of defining routes, add the following lines to your index.php in your public folder:


            ...
            $app = new NeoanApp( $setup, $cliPath);

            // enable attribute routing
            $namespaceToExploreRecursively = 'App';

            $app->invoke(new Neoan\Routing\AttributeRouting($namespaceToExploreRecursively));

            $app->run();
        

Examples

Attribute
Description
Example

Web

Resolves html routes

#[Web('/test', 'test.html')]

Get

Resolves API-GET routes

#[Get('/api/test')]

Post

Resolves API-GET routes

#[Post('/api/test', AuthGuard::class)]

Put

Resolves API-PUT routes

#[Put('/api/test', AuthGuard::class)]

Generally, the behavior is identical to declaring routes manually.


            ?php
            namespace App;

            // Don't forget the use-statement!
            use Neoan\Routing\Attributes\Get;

            use Neoan\Routing\Interfaces\Routable;

            #[Get('/api/test')]
            class Controller implements Routable
            {
                public function __invoke(): array
                {
                    return ['test' => 'message'];
                }
            }

        

Before you move on

Many references on this page assume default settings. Your project might differ in behavior, paths etc.