Skip to main content

Middleware

Middleware in Serapha allows you to filter and manipulate HTTP requests entering your application. They are commonly used for tasks such as authentication, logging, and request modification.

Basic Structure​

Middleware Base Class​

All middleware classes must extend the Middleware base class, which defines the process method. This method will be executed for each request that the middleware is applied to.

Creating Middleware​

To create a middleware, extend the Middleware class and define your middleware logic within the process method.

Example: AuthMiddleware​

The AuthMiddleware checks if a user is authenticated before allowing the request to proceed.

app/Middleware/AuthMiddleware.php
namespace App\Middleware;

use Serapha\Routing\Response;
use Serapha\Routing\Request;
use Serapha\Routing\Handler;
use Serapha\Middleware\Middleware;

class AuthMiddleware extends Middleware
{
public function process(Request $request, Response $response, Handler $handler): Response
{
// Check if the user is logged in
if ($this->sessionManager->get('user') === null) {
// If not logged in, redirect to the login page
return $response->withRedirect('/login');
}

// If logged in, continue processing the request
return $handler->handle($request, $response);
}
}

Using Middleware in Routes​

Middleware can be added to routes to be executed before the controller action is invoked. Here is an example showing how to add middleware to a route.

Routing with Middleware​

In this example, the AuthMiddleware is registered and run before the create action in the UserController.

app/Route/routes.php
use App\Controller\{
HomeController,
UserController,
APIController,
AuthController
};
use App\Middleware\AuthMiddleware;
use Serapha\Routing\Route;
use Serapha\Routing\Response;

// Regular routes
Route::get('/', [HomeController::class]);
Route::middleware(AuthMiddleware::class)->get('/user/create', [UserController::class, 'create']);
Route::middleware(AuthMiddleware::class)->post('/user/create', [UserController::class, 'store']);
Route::get('/user/{id}', [UserController::class, 'show']);
Route::get('/login', [AuthController::class, 'index']);
Route::post('/login', [AuthController::class, 'store']);

// Route without controller
Route::get('/test/{param}', static function (string $param = 'World'): Response {
$response = new Response();
$response->getBody()->write('Hello ' . $param);

return $response;
})->where('param', '[0-9a-zA-Z]+');

// Middleware and group routes
Route::prefix('admin')->middleware(AuthMiddleware::class)->group(function () {
Route::get('/dashboard', [UserController::class, 'dashboard']);
Route::get('/profile', [UserController::class, 'profile']);
Route::get('/settings', [UserController::class, 'settings']);
});

// API routes
Route::prefix('api')->group(function () {
Route::get('/user/{param}', [APIController::class, 'param'])->where('param', '[a-z]+');
Route::get('/user/{id}/{name?}', [APIController::class, 'show'])->where(
[
'id' => '[0-9]+',
'name' => '[a-zA-Z]+'
]
);
Route::get('/user/create', [APIController::class, 'index']);
});

Global Middleware​

You can also add global middleware that will be executed for every request. To add global middleware, use the middleware method on the Router instance.

$router = $core->getContainer()->get(Router::class);
$router->middleware([AuthMiddleware::class]);

Middleware Stack​

Serapha allows you to run a stack of middleware for each request. The middleware are executed in the order they are added.

Example of Middleware Stack​

In this example, multiple middleware can be stacked and executed in sequence.

$router->middleware([
MiddlewareOne::class,
MiddlewareTwo::class
]);
$router->handleRequest();

Dependency Injection​

Serapha supports Dependency Injection (DI) for middleware, making it easy to manage dependencies within your middleware.

Example: Using DI in Middleware​

namespace App\Middleware;

use Serapha\Middleware\Middleware;
use carry0987\SessionManager\SessionManager;

class ExampleMiddleware extends Middleware
{
private SessionManager $session;

public function __construct(SessionManager $session)
{
$this->session = $session;
// Your middleware logic here
}

// Define other methods for your middleware
}

Conclusion​

Middleware in Serapha provides a powerful mechanism to handle common tasks such as authentication, logging, and request modification. By extending the Middleware class and using the Router to manage middleware, you can easily extend and secure your application.

By following this guide, you should be able to create and apply middleware effectively in your Serapha application.