Attributes Usage
Laraventus adds support for PHP attributes to define middleware directly above your controller methods, making your code cleaner and more expressive.
Enabling Attribute Middleware
Section titled “Enabling Attribute Middleware”This feature is enabled by default. To disable it, change the configuration file laraventus.php:
<?php
return [ "controller" => [ "attributes" => false ],];This middleware automatically scans for attributes that extend Aventus\Laraventus\Attributes\Middleware and executes them when attached to controller methods.
Creating a Custom Attribute Middleware
Section titled “Creating a Custom Attribute Middleware”Let’s create a simple example that denies access to a route.
Create the Attribute
Section titled “Create the Attribute”<?php
namespace App\Http\Middlewares;
use Attribute;use Aventus\Laraventus\Attributes\Middleware;use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response;use Illuminate\Http\JsonResponse;
#[Attribute(Attribute::TARGET_METHOD)]class Deny extends Middleware{ public function __construct() { parent::__construct(Deny::class); }
public function handle(Request $request, Closure $next): Response { return new JsonResponse([], 403); }}- The
#[Attribute]decorator makes the class usable as a PHP attribute. - It extends
Aventus\Laraventus\Attributes\Middleware, allowing Laraventus to detect and execute it automatically. - The
handlemethod defines what happens when the middleware is triggered. Here, it simply returns a 403 Forbidden JSON response.
Apply the Attribute to a Route
Section titled “Apply the Attribute to a Route”Now you can use it directly above your controller method:
<?php
namespace App\Http\Controllers\HelloWorld;
use App\Http\Middlewares\Deny;
class Controller{ #[Deny] public function request(Request $request): Error|Response { return new Response("Hello " . $request->name); }}When the route is called, the Deny middleware runs before the controller logic and stops execution, returning a 403 response.
Result
{ "result": [], "errors": [], "$type": "Aventus.Laraventus.Helpers.LaravelResult"}With an HTTP status: 403 Forbidden
Advanced Example: Transaction Attribute
Section titled “Advanced Example: Transaction Attribute”In more complex scenarios, you might want to automatically wrap your controller logic in a database transaction. Committing only when everything succeeds, and rolling back if any error occurs.
With Laraventus, you can achieve this cleanly using an Attribute-based middleware.
Create the Transaction Attribute
Section titled “Create the Transaction Attribute”<?php
namespace App\Http\Middlewares;
use Attribute;use Aventus\Laraventus\Attributes\Middleware;use Aventus\Laraventus\Helpers\AventusError;use Aventus\Laraventus\Helpers\LaravelResult;use Closure;use Exception;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response;use Illuminate\Support\Facades\DB;use Illuminate\Http\JsonResponse;use Illuminate\Http\Response as HttpResponse;
#[Attribute(Attribute::TARGET_METHOD)]class Transaction extends Middleware{ public function __construct() { parent::__construct(Transaction::class); }
public function handle(Request $request, Closure $next): Response { DB::beginTransaction();
try { $response = $next($request);
if ($response instanceof Response) { if ($response instanceof JsonResponse || $response instanceof HttpResponse) { $data = $response->getOriginalContent();
if ($data instanceof LaravelResult && count($data->errors) > 0) { DB::rollBack(); } else if ($data instanceof AventusError) { DB::rollBack(); } else { DB::commit(); } } else { DB::commit(); } }
return $response; } catch (Exception $e) { DB::rollBack(); throw $e; } }}Apply the Attribute to Your Controller
Section titled “Apply the Attribute to Your Controller”<?php
namespace App\Http\Controllers\User;
use App\Http\Middlewares\Transaction;
class Controller{ #[Transaction] public function changeName(Request $request): Error|Response { // All database operations inside this method // will be executed within a transaction.
// Example: // $user = User::find($request->id); // $user->name = $request->newName; // $user->save();
return new Response("User name changed successfully"); }}When the controller is executed:
- A database transaction begins before your code runs.
- If your controller (or any middleware) throws an exception or returns an AventusError / LaravelResult containing errors, the transaction rolls back.
- If everything succeeds, the transaction commits automatically.
Summary
Section titled “Summary”By using attribute-based middlewares, Laraventus lets you:
- Define custom logic (e.g., access control, logging, rate limiting) directly above your route functions.
- Keep your controller code clean and self-contained.
- Maintain strong typing and structure consistent with Laravel’s conventions but with the added simplicity of attribute-driven behavior