Fix action caller next middleware handling #210
Conversation
That is likely true. Maybe instead of fixing |
Nothing will happen, it is just an alias to the to() method. Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->prepend(function (ServerRequestInterface $request, RequestHandlerInterface $handler) use ($container) {
$response = $container->get(ResponseFactoryInterface::class)->createResponse();
return $response;
}) or a little bit better Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware(function (ServerRequestInterface $request, RequestHandlerInterface $handler) use ($container) {
$response = $container->get(ResponseFactoryInterface::class)->createResponse();
return $response;
}) |
Maybe instead of removing |
$route
->before($middleware1)
->before($middleware2)
->before($middleware3) Which order it will have after compiling rules? |
Names don't matter. Route::get('/')
->to(function () {
//doing something
})
->to(function () {
//doing something
})
->to(new ActionCaller(SiteController::class, 'index', $container))
->to(function () {
//doing something
})
->to(function () {
//doing something
})
->name('site/index'), Route::get([
'/' => 'site/index',
[
function () {
//doing something
},
function () {
//doing something
},
new ActionCaller(SiteController::class, 'index', $container),
function () {
//doing something
},
function () {
//doing something
}
]
]); |
There is no differ between
|
I think we should leave one method, that adds (prepends in our case) a middleware. with the "main" action method (a middleware that will be prepended first) Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware($middleware1) // ->prepend($middleware1)
->addMiddleware($middleware2) // ->prepend($middleware2); or without Route::get('/')
->addMiddleware(new ActionCaller(SiteController::class, 'index', $container)) //or ->prepend(new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware($middleware1) // or ->prepend($middleware1)
->addMiddleware($middleware2) //or ->prepend($middleware2); They are equal. But in my opinion the first option is easier for beginners. |
I think we should leave both methods, just need to fix the middlewares (ActionCaller, Callback, WebActionsCaller) |
For what purpose? |
@yiiliveext keep calm please. Route::get('/')
->next($beforeMiddleware)
->next($controllerAction)
->next($afterMiddleware)
->next($afterMiddleware) But short syntax |
A single way to do it preferred but we should name it right. |
use Psr\Http\Server\MiddlewareInterface as Middleware;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
Route::method(string $path)
->to(RequestHandler|Closuer|string $controller)
->add(Middleware|Closure|string $middleware)
->add(Middleware|Closure|string $middleware)
->name(string $name);
// or
Route::method(string $path, RequestHandler|Closuer|string|null $controller = null)
->add(Middleware|Closure|string $middleware)
->add(Middleware|Closure|string $middleware)
->name(string $name); In both cases, the |
I agree and proposed it above.
Don't worry, I'm as cool as a cucumber.
next() is not an appropriate method name. Middlewares work as a stack, which means the LIFO (Last In First Out) way used, so Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware($middleware1)
->addMiddleware($middleware2); Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->prependMiddleware($middleware1)
->prependMiddleware($middleware2); |
Route::get('/')
->to($beforeMiddleware)
->to(new ActionCaller(SiteController::class, 'index', $container))
->to($afterMiddleware) Route::get('/')
->to(new ActionCaller(SiteController::class, 'index', $container))
->prepend($beforeMiddleware)
->then($afterMiddleware) They are the same, there is no logical difference, as @yiiliveext said above. But they differ slightly in design, the second case is more readable than the first. |
What about this Route::get('/')
->to(new ActionCaller(SiteController::class, 'index', $container))
->prepend($middleware1)
->to($middleware2)
->then($middleware3)
->prepend($middleware4)
->then($middleware5) Looks like it is not very clear. What do you think? |
Your opinion is also not clear Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->prependMiddleware($middleware1)
->addMiddleware($middleware2)
->prependMiddleware($middleware3)
->addMiddleware($middleware4); // can be infinity We cannot manage the approach for each user |
You don't understand. We have either the Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware($middleware1)
->addMiddleware($middleware2)
->addMiddleware($middleware3)
->addMiddleware($middleware4); $middleware4 will be processed first, $middleware3 will be processed when $middleware4 has called $handler->handle($request) and so on. |
OK. I got you, so that the ActionCaller will be processed last? |
Yes, it is. |
If someone wants to add middleware after ActionCaller what should to do it? |
If you want to execute some code after an action you can do it in any middleware Route::get('/', new ActionCaller(SiteController::class, 'index', $container))
->addMiddleware(function (ServerRequestInterface $request, RequestHandlerInterface $handler) {
//do something before the index action
$response = $handler->handle($request);
//do something after the index action
return $response;
}); See an example in the first post #210 (comment). I check the query params before the test action and log the body after. |
@rustamwin add it before and design middleware like: function (ServerRequestInterface $request, RequestHandlerInterface $handler) {
$response = $handler->handle($request);
// do your stuff
return $response;
} |
This particular change is 👍 Let's remove confusing methods separately. |
@samdark yes I know, probably we should add it to docs |
There is the next example.
Route
Action
Don't be scared, this is just my test case:) The first middleware prepended in the prepend() method fires successfully. The second middleware prepended in the then() method does not.
Of cause, I can do like this and evrerything will be ok.
But is it what we expect? I dont think so.
P.S. Basically I do not know why then() method is needed. Everything I want I can do with a prepended middleware.