Group middleware is a way to bundle multiple middleware under one group name, so you don’t have to manually list every single middleware for every route.
Instead of this:
['checkAge', 'checkRole', 'logRequest']
You can do:
['authGroup']
Where authGroup is mapped to those three middleware.
🧱 Example in Laravel-style
In Laravel:
Route::middleware(['authGroup'])->group(function () {
// routes here
});
Where in Kernel.php:
'authGroup' => [
\App\Http\Middleware\CheckAge::class,
\App\Http\Middleware\CheckRole::class,
\App\Http\Middleware\LogRequest::class,
],
✅ Let’s Implement Group Middleware in Your Custom System
📁 Step-by-step Structure Recap
We’ll enhance your current setup by adding:
✅ Middleware registry
✅ Group definitions
✅ Logic to resolve group names into middleware arrays
You can check my private git repo here to see working example.
✅ Step 1: Middleware definitions
$checkAge = function ($request, Closure $next) {
if ($request['age'] < 18) {
return "You must be 18+";
}
return $next($request);
};
$checkRole = function ($request, Closure $next) {
if ($request['role'] !== 'admin') {
return "Access denied. Admins only.";
}
return $next($request);
};
$logRequest = function ($request, Closure $next) {
echo "Logging request...\n";
return $next($request);
};
✅ Step 2: Middleware Group Registry
$middlewareGroups = [
'authGroup' => [
'checkAge',
'checkRole',
'logRequest',
],
];
✅ Step 3: Middleware Lookup Table (by name)
$middlewareMap = [
'checkAge' => $checkAge,
'checkRole' => $checkRole,
'logRequest' => $logRequest,
];
✅ Step 4: Group Resolver Function
The group resolver builds a final array of middleware functions that will be passed into the pipeline (defined in the manager file).
function resolveMiddlewares(array $middlewares, array $groups, array $map) {
$resolved = [];
foreach ($middlewares as $key) {
if (isset($groups[$key])) {
foreach ($groups[$key] as $grouped) {
$resolved[] = $map[$grouped];
}
} elseif (isset($map[$key])) {
$resolved[] = $map[$key];
}
}
return $resolved;
}
✅ Step 5: Controller
$controller = function ($request) {
return "Welcome, {$request['user']}!";
};
✅ Step 6: Pipeline Builder (same as before)
function buildPipeline(array $middlewares, Closure $controller)
{
return array_reduce(
array_reverse($middlewares),
function ($next, $middleware) {
return function ($request) use ($middleware, $next) {
return $middleware($request, $next);
};
},
$controller
);
}
✅ Step 7: Simulate Router / Request
$request = [
'user' => 'Dilip',
'age' => 22,
'role' => 'admin'
];
// Middleware group to apply
$routeMiddleware = ['authGroup']; // could also be ['checkAge', 'logRequest']
$resolvedMiddleware = resolveMiddlewares($routeMiddleware, $middlewareGroups, $middlewareMap);
$pipeline = buildPipeline($resolvedMiddleware, $controller);
$response = $pipeline($request);
echo $response;
🧪 Sample Output:
Logging request...
Welcome, Dilip!
(Change role to user, and you’ll see: Access denied. Admins only.)
✅ Final Summary: Middleware Group in Your Mini PHP App
| Concept | Code Element |
|---|---|
| Middleware | $checkAge, $checkRole, $logRequest |
| Group definition | $middlewareGroups['authGroup'] |
| Name mapping | $middlewareMap |
| Resolver function | resolveMiddlewares() |
| Pipeline executor | buildPipeline() |
| Entry point | Simulated “route” that applies a group |
🏙️ Middleware Group Analogy in a Multi-Lift Building
🛗 Scenario:
Imagine the Burj Khalifa — it’s a very tall building, so it doesn’t have just one lift.
Instead, it has lift zones, like:
- Lift A: Floors 1–20
- Lift B: Floors 21–50
- Lift C: Floors 51–100
Each lift services a specific group of floors.
🔁 Mapping to Middleware Groups
| Building Concept | Middleware System Equivalent |
|---|---|
| Multi-floor building | Your application / route system |
| Lift Zones (A, B, C) | Middleware Groups (web, api, authGroup) |
| Floor buttons in a lift | Individual middleware in that group |
| Passenger | The incoming request |
| Final floor destination | The controller / final response |
✅ Example
Let’s say you’re in Lift B (Floors 21–50). It always goes through:
- Floor 21:
checkAge - Floor 25:
checkRole - Floor 40:
logRequest - Floor 50: Final destination (controller)
This Lift B is your authGroup middleware group in Laravel.
🧠 Why is this powerful?
Instead of defining all individual floor stops every time, you can just say:
“This route takes Lift B (authGroup)”
Laravel (or your manager) will know:
- Which floor stops (middlewares) to include
- In what order
- And how to pass the request from one to another
✅ Analogy Summary
In a super-tall building, lifts are grouped to handle certain floor ranges.
Similarly, in your app, middleware groups are bundled sets of middleware to handle related tasks — like auth, logging, throttling, etc.
You assign a route to a group lift, and it stops at the right middleware floors automatically.
🧾 Real Laravel Mapping
'authGroup' => [
'checkAge',
'checkRole',
'logRequest'
];
Route::middleware(['authGroup'])->get('/dashboard', fn() => 'Dashboard');
👆 Laravel knows:
“This request takes Lift B — so it should stop at those floors before reaching the controller.”
