-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Adding arbitrary middlewares to command & query routes #5
Comments
From @prolic on November 9, 2017 11:33 I think we would need pre- and post-middlewares. The metadata gatherer can then be removed as option and simply added to the pre-middleware list. |
As it stands the MetadataGatherer isn't technically a Middleware |
From @prolic on November 9, 2017 12:20 Ok my bad On Nov 9, 2017 8:13 PM, "Bas Kamer" [email protected] wrote:
|
I believe the biggest hurdle is to somehow insert the given middlewares list into the pipeline of the current route and have those execute from within the executing Command- & QueryMiddleware. Any idea on how to do that? |
https://zendframework.slack.com/archives/C4QBQUEG5/p1509550722000242 @danizord could you share your experiences and perhaps have some advise |
From @weierophinney on November 13, 2017 15:32 @prolic https://zendframework-slack.herokuapp.com for invites. |
From @prolic on November 13, 2017 16:21 I am not sure, just a shot into the blue:
|
From @danizord on November 13, 2017 19:39
@basz @prolic you can also do that with use Zend\Expressive\Middleware\LazyLoadingMiddleware;
use Zend\Stratigility\MiddlewarePipe;
$pipeline = new MiddlewarePipe();
$response = new Response();
foreach ($middlewares as $middleware) {
$pipeline->pipe(new LazyLoadingMiddleware($container, $response, $middleware));
}
$pipeline->process($request, $queryOrCommandMiddleware); Having said that, let me show you the approach (a bit unrelated) that I've been working with. Most middlewares would require different configuration for each route, e.g an I can see in your example that this package solves that using route options, but it has some problems:
The approach I'm using to solve that is passing these configuration as params to middleware constructors and creating different instances for each route: // These with "Factory" suffix are custom factories that already contains dependencies
// injected by the container and expects the configuration to create actual middlewares.
$inputValidation = $container->get(InputValidationMiddleware::class);
$createQuery = $container->get(CreateQueryMiddlewareFactory::class);
$createCommand = $container->get(CreateCommandMiddlewareFactory::class);
$dispatchCommand = DispatchCommandMiddleware::class;
$dispatchQuery = DispatchQueryMiddleware::class;
$commandResponse = new CommandResponseMiddleware();
$queryResponse = $container->get(QueryResponseMiddlewareFactory::class);
// Ping
$app->get('/internal/ping', $commandResponse->withSuccessMessage('ok'));
// ScheduleReminder
$app->post('/api/reminders', [
// I'm using with* methods because I found it more readable, but it can be pure
// callables like $inputValidation('schedule-reminders.json')
$inputValidation->withJsonSchema('schedule-reminders.json'),
// Thanks to callable typehint, PHPStorm recognizes it as the class static method,
// So you can refactor, find usages, click to navigate and such :)
$createCommand->withCommandFactory([UpdateSettings::class, 'fromRequest']),
// This middleware does not require any configuration, so we don't need to
// instantiate it here, we can pass the name and Expressive will lazy instantiate it
$dispatchCommand,
// Some middlewares wouldn't need dependencies from container, so you don't need
// to create a custom factory, you can implement immutbale with* methods like PSR-7
$commandResponse->withRedirectTo('/api/reminders/{id}'),
]);
// GetReminders
// You can see how the middleware pipeline looks very readable :)
$app->get('/api/reminders', [
$createQuery->withQueryFactory([GetReminders::class, 'fromRequest']),
$dispatchQuery,
$queryResponse->withResourceClass(ReminderResource::class),
]); |
Thank you @danizord lots to play with and contemplate. I'll start with the MiddlewarePipe thing, but I think @prolic and @codeliner should have a read over your second point. Definitely a BC but it might be worth investigating... |
From @sprolic-modus on November 14, 2017 8:16 BC is not a problem, as we have only dev-releases so far and not even 1.0 final. |
From @sprolic-modus on November 14, 2017 8:18 @danizord your approach loads all the middlewares for all requests, despite of being used, right? I kind of don't like that. |
From @danizord on November 14, 2017 10:6 @sprolic-modus if this is hurting performance, you can do some workaround to pipe the middlewares lazily: $app->get('/api/reminders', lazyPipeline(function () use ($container) {
// Pull from container...
return [
$createQuery->withQueryFactory([GetReminders::class, 'fromRequest']),
$dispatchQuery,
$queryResponse->withResourceClass(ReminderResource::class),
];
})); But the syntax starts to become confusing (would be nice if PHP had arrow functions) :D Also since the middleware pipeline is stateless, you can use PHPFastCGI, ReactPHP or something like that to bootstrap once and keep running. |
From @codeliner on November 14, 2017 20:20 @sprolic-modus are you the real @prolic ? :D @danizord I really like the approach, but would definitely go with the lazyPipeline approach. |
From @codeliner on November 14, 2017 20:39 @weierophinney Why slack? :D I mean we use it for work and it is working fine but for an OSS project hosted on github we really like gitter. People can join with their github or twitter account and directly start asking questions. And gitter is completely open source. |
From @prolic on November 14, 2017 20:45 Confirming, sprolic-modus is me. Sorry was logged in wrong account. This On Nov 15, 2017 4:40 AM, "Alexander Miertsch" [email protected] @weierophinney https://github.com/weierophinney Why slack? :D I mean we use it for work and it is working fine but for an OSS project — Reply to this email directly, view it on GitHub |
From @codeliner on November 14, 2017 20:50 ah ok. @sprolic-modus sounds like your hacker account (hopefully white hat) :P |
From @sprolic-modus on November 14, 2017 20:55 Haha On Nov 15, 2017 4:50 AM, "Alexander Miertsch" [email protected]
|
From @weierophinney on November 14, 2017 21:25
Not going to debate it again. It works for us, and, frankly, developer engagement has gone way up since we started using it. |
From @codeliner on November 14, 2017 21:28 interesting. thx @weierophinney and definitely better than IRC. Never was a fan of IRC, though |
From @prolic on December 23, 2017 13:47 @basz Please move this issue to https://github.com/prooph/http-middleware/ |
From @basz on November 9, 2017 9:2
To add additional middleware to prooph routes one currently has to add those manually to each defined route.
eg.
We could introduce a way so QueryMiddleware and CommandMiddleware are capable of adding arbitrary middlewares so it can be easily configured.
I'm thinking of this configuration bit and some factory modifications;
These 'middlewares' would need to be fetched from the container by Command and Query Factories and passed to the Command and QueryMiddlewares whom should process them in order and before the MetadataGatherer runs.
Shouldn't be too difficult, thoughts?
Copied from original issue: prooph/psr7-middleware#29
The text was updated successfully, but these errors were encountered: