ensi / laravel-initial-event-propagation
Laravel initial event propagation
Installs: 78 907
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 2
Open Issues: 1
pkg:composer/ensi/laravel-initial-event-propagation
Requires
- php: ^8.1
- ensi/initial-event-propagation: ^0.3.0
- laravel/framework: ^9.0 || ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.2
- orchestra/testbench: ^7.0 || ^8.0 || ^9.0 || ^10.0
- pestphp/pest: ^1.22 || ^2.0 || ^3.0
- pestphp/pest-plugin-laravel: ^1.1 || ^2.0 || ^3.0
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.11
- psr/http-message: ^1.0 || ^2.0
- spaze/phpstan-disallowed-calls: ^2.15
README
Provides a bunch of ready-to use middleware to integrate ensi/initial-event-propagation in Laravel application. You are free to replace any of them with your own implementations.
Installation
You can install the package via composer:
composer require ensi/laravel-initial-event-propagation
Publish config file like this:
php artisan vendor:publish --provider="Ensi\LaravelInitialEventPropagation\LaravelInitialEventPropagationServiceProvider"
Version Compatibility
| Laravel IEP | Laravel | PHP |
|---|---|---|
| ^0.1.0 | ^8.x | ^8.0 |
| ^0.2.0 | ^8.x | ^8.0 |
| ^0.2.5 | ^8.x || ^9.x | ^8.0 |
| ^0.2.6 | ^8.x || ^9.x | ^8.1 |
| ^0.2.9 | ^8.x || ^9.x || ^10.x | ^8.1 |
| ^0.2.11 | ^8.x || ^9.x || ^10.x || ^11.x | ^8.1 |
| ^0.3.0 | ^9.x || ^10.x || ^11.x | ^8.1 |
Basic Usage
$holder = resolve(InitialEventHolder::class); var_dump($holder->getInitialEvent()); $holder->setInitialEvent(new InitialEventDTO(...));
You must always resolve InitialEventHolder from the service container instead of InitialEventHolder::getInstance.
This is made forLaravel Octane compatibility.
HTTP Requests
Setting initial event
You typically create a new initial event when you receive a HTTP request coming from a client you do not own. E.g in an API Gateway.
There is a built-in Ensi\LaravelInitialEventPropagation\SetInitialEventHttpMiddleware for that.
It creates an InitialEventDTO and places it to the InitialEventHolder singleton.
userIdandentrypointare set from request.appis set according to config options.userTypeis set from the package config.userTypeis empty for a not authenticated user.correlationIdandtimestampare set from request headers according to config options or generated from scratch.realUserId,realUserTypeandmiscare left empty strings.
Be sure to add the midlleware AFTER Laravel middleware that sets authenticated user.
In practice it likely means that you have to place the middleare at the very bottom of middlewareGroups in app/Http/Kernel
Parsing incoming initial event
Add Ensi\LaravelInitialEventPropagation\ParseInitialEventHeaderMiddleware to app/Http/Kernel middleware property.
This middleware parses X-Initial-Event HTTP header, deserializes it into InitialEventDTO object and places it to the InitialEventHolder singleton.
Propagating initial event to outcomming HTTP request
The package provides a Ensi\LaravelInitialEventPropagation\PropagateInitialEventLaravelGuzzleMiddleware Guzzle Middleware that converts resolve(InitialEventHolder::class)->getInitialEvent() back to X-Initial-Event header and sets this header for all outcomming guzzle request.
You can add it to your guzzle stack like this:
$handlerStack = new HandlerStack(Utils::chooseHandler()); $handlerStack->push(new PropagateInitialEventLaravelGuzzleMiddleware());
CLI
Artisan Commands
There is a custom artisan Ensi\LaravelInitialEventPropagation\SetInitialEventArtisanMiddleware that sets new initial event in every artisan command that you run.
You can add it to the app\Console\Kernel like that:
public function bootstrap() { parent::bootstrap(); (new SetInitialEventArtisanMiddleware())->handle(); }
This middleware sets artisan command name (including argument, excluding options) as $initialEventDTO->entrypoint.
If your custom artisan command makes guzzle HTTP requests to other apps the PropagateInitialEventGuzzleMiddleware uses this initial event.
This middleware also works fine for Laravel Task Scheduling.
Queue Jobs
You typically want to persist initial event between incoming HTTP request and queued job.
The package can help you here aswell. Unfortunately you need to touch a given job:
use Ensi\LaravelInitialEventPropagation\Job; // Extend the job from package class TestJob extends Job implements ShouldQueue { public function __construct(protected Customer $customer) { // Do not forget to call parent constuctor parent::__construct(); } public function handle() { // InitialEvent is automatically persisted to InitialEventHolder via job middleware in parent class, // You do not need to persist it manually } }
Laravel Queable Actions
If you use spatie/laravel-queueable-action package to dispatch actions instead of jobs you do not need to mess with every job separately.
Just publish laravel-queueable-action config and set the special Job class there:
'job_class' => \Ensi\LaravelInitialEventPropagation\ActionJob::class,
Contributing
Please see CONTRIBUTING for details.
Testing
- composer install
- composer test
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
License
The MIT License (MIT). Please see License File for more information.