slimphp / Slim

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
http://slimframework.com
MIT License
11.98k stars 1.95k forks source link

app middleware is not invoked when doing subRequest #1339

Closed kminek closed 9 years ago

kminek commented 9 years ago

sample code:

$app = new Slim\App();

$app->add(function ($req, $res, $next) {
    $res->write('BEFORE');
    return $next($req, $res);
});

$app->get('/', function ($request, $response, $args) {
    return $this->subRequest('GET', '/hello/grzes');
});

$app->get('/hello/{name}', function ($request, $response, $args) {
    $response->write("Hello, " . $args['name']);
    return $response;
});

$app->run();
JoeBengalen commented 9 years ago

That is the expected behaviour as far as I know.

Lewiscowles1986 commented 9 years ago

Surely the subRequest could be replaced with an API call or command pattern; if for example Auth and ACL, session data etc was needed, this would also be more descriptive. Using this command pattern in each route (the /hello/{name} request, and the '/') call a command and can share data from the app's di container. Is this the desired reason for using middleware on subRequest?

kminek commented 9 years ago

to be honest i would like not to use subRequest at all. i wish something like following was possible:

$app->get('/hello/{name}', 'HelloController:hello');
$app->get('/', 'HelloController:hello')->setParam('name', 'grzes');
Lewiscowles1986 commented 9 years ago

it is possible, but not using just slim. The point of a micro-framework is to be able to bolt-in other libraries. I recommend https://github.com/jmathai/php-multi-curl. It has some pretty simple syntax, and if you need to add params just implode the values with the relevant separators.

Please also bear in mind this is not the best solution to calling other URL endpoints, but it will get you motoring, and if you target a specific domain, that has load balancing, it can be a poor man's load distribution.

kminek commented 9 years ago

@Lewiscowles1986 man, i'm not talking about making curl requests. i'm talking about Route class feature that is missing in 3 but was in 2: https://github.com/slimphp/Slim/blob/2.x/Slim/Route.php#L259

Lewiscowles1986 commented 9 years ago

@kminek Sorry I don't understand why you would want to do this. From what maybe is my limited understanding of your goal, or problem, it seems easier to just send another request. Personally I would use command pattern for this rather than a route, then you can set data for the command.

akrabat commented 9 years ago

One option would be to write as middleware:

$app->add(function($request, $response, $next) {
    if ($request->getMethod() == 'GET' &&
        $request->getUri()->getPath() == '/') {
        $request = $request->withUri($request->getUri()->withPath('/hello/rob'));
    }
    return $next($request, $response);
});
akrabat commented 9 years ago

Interestingly, the discussion is completely off topic in terms of the actual reported issue.

In order for the code to work as you would expect, you have to pass the response object to the subRequest() like this:

$app->get('/', function ($request, $response, $args) {
    return $this->subRequest('GET', '/hello/grzes', '', [], [], '', $response);
});

This is because subRequest() will pull a new Response object out of the container if you don't pass one in.

There's a reasonable argument that $response should be the first argument to subRequest().

/cc @silentworks

kminek commented 9 years ago

@akrabat ok that makes sense now - thx.