Installation
composer require equip/dispatch
Add the middleware to your Laravel HTTP kernel (app/Http/Kernel.php):
protected $middleware = [
// ...
\Equip\Dispatch\Middleware\DispatchMiddleware::class,
];
First Use Case
Define a middleware group in app/Http/Kernel.php:
protected $middlewareGroups = [
'dispatch' => [
\Equip\Dispatch\Middleware\DispatchMiddleware::class,
],
];
Register the group in routes/web.php:
Route::middleware(['dispatch'])->group(function () {
Route::get('/example', [ExampleController::class, 'index']);
});
Basic Dispatch Configuration
Create a dispatch.php config file in config/ (published via php artisan vendor:publish --provider="Equip\Dispatch\DispatchServiceProvider"):
return [
'middleware' => [
'auth', // Default middleware stack
'throttle:60',
],
'dispatchers' => [
'api' => [
'middleware' => ['api', 'throttle:api'],
],
],
];
Dynamic Middleware Stacks
Use the dispatch middleware to dynamically apply middleware based on request attributes (e.g., headers, route parameters):
// In a controller or middleware
app(\Equip\Dispatch\Dispatcher::class)->dispatch('custom-stack');
Route-Based Dispatching Attach dispatchers to routes via metadata:
Route::get('/admin', [AdminController::class, 'index'])
->middleware(['dispatch:admin']);
Conditional Dispatching Leverage middleware conditions to toggle dispatchers:
// In config/dispatch.php
'dispatchers' => [
'admin' => [
'middleware' => ['auth', 'admin'],
'conditions' => function ($request) {
return $request->user()?->isAdmin();
},
],
];
Laravel Events
Trigger dispatchers from events (e.g., Illuminate\Auth\Events\Attempting):
event(new Attempting($credentials, $remember));
app(\Equip\Dispatch\Dispatcher::class)->dispatch('auth-attempt');
Service Container Binding Bind custom dispatchers for modularity:
$this->app->bind('custom.dispatcher', function () {
return new CustomDispatcher();
});
API Gateway Patterns
Use dispatchers to route requests to different services (e.g., dispatch:service-a).
Middleware Ordering
Dispatch middleware runs after the default stack. Ensure critical middleware (e.g., auth) is included in both the default and dispatcher stacks to avoid bypassing them.
Circular Dependencies
Avoid recursive dispatch calls (e.g., a dispatcher triggering another that loops back). Use a visited flag or middleware priority to prevent this.
Configuration Overrides
Dispatcher configs in routes.php or middleware override config/dispatch.php. Test edge cases where multiple configs might conflict.
Middleware Dump
Use Laravel’s middleware artisan command to inspect the full stack:
php artisan middleware:list
Filter for DispatchMiddleware to debug the active stack.
Logging Dispatchers
Add debug logging to DispatchMiddleware:
\Log::debug('Dispatching stack:', $this->dispatcher->getStack());
Custom Dispatchers
Extend Equip\Dispatch\Dispatcher to create reusable stacks:
class ApiDispatcher extends Dispatcher {
public function __construct() {
$this->middleware = ['api', 'throttle:api'];
}
}
Middleware Conditions Use closures or callables for dynamic conditions:
'dispatchers' => [
'feature-flag' => [
'middleware' => ['feature:new-ui'],
'conditions' => fn ($request) => config('features.new_ui.enabled'),
],
];
PSR-15 Middleware The package supports PSR-15 middleware. Register them in the dispatcher stack:
$dispatcher->addMiddleware(new Psr15Middleware());
Priority Handling
Middleware defined in dispatchers take precedence over the default stack. Explicitly merge stacks if needed:
'middleware' => array_merge(config('dispatch.middleware'), ['additional']),
Environment-Specific Dispatchers Use Laravel’s config caching to manage environment-specific dispatchers:
// config/dispatch.php
'dispatchers' => env('APP_ENV') === 'local' ? ['debug'] : [],
How can I help you explore Laravel packages today?