How to use redirect in Slim4?

Hellow!
I’m using Slim4 for simple RestAPI (/api/app.php & /api/routes.php & some Actions classes).
Now it has become necessary to make v2 fore some routes (other mast be redirected to v1). And here the problem starts
redirect() answer: 405 NOT ALLOWED

May be problem with grouping?

$app->group('/v1', function (Group $group) {
    $group->group('/user', function (Group $group) {
        $group->post('/register', RegisterAction::class)->setName('register');
        $group->post('/authorize', AuthorizeAction::class)->setName('authorize');
       $group->post('/current', CurrentAction::class)->setName('current');
       ....
   });
....
});

$app->group('/v2', function (Group $group) {
    $group->redirect('/user/current', '/api/v1/user/current', 302);
...
});

Do you also have a group for /api?

no, base path is ‘/api’

$app = AppFactory::create();

$app->setBasePath(’/api’);

$contentLengthMiddleware = new ContentLengthMiddleware();
$app->add($contentLengthMiddleware);
$app->addBodyParsingMiddleware();
$app->addRoutingMiddleware();

I tried $group->redirect(’/user/current’, ‘/v1/user/current’, 302);
but it shows answer for url https://site/v1/user/current

“405 NOT ALLOWED” means HTTP method not allowed. The redirect is a GET request.
Do you have a route for a path like GET /v1/user/current ?

For example:

$app->group('/v1', function (RouteCollectorProxy $group) {
    $group->group('/user', function (RouteCollectorProxy $group) {
        $group->get('/current', UserCurrentAction::class)->setName('v1.user.current');
       // ....
   });
    // ...
});

/api/v1/user/current is POST
(all v1 api work correct)
Extend test:

$app->group('/v1', function (Group $group) {
    $group->group('/user', function (Group $group) {
        $group->post('/current', CurrentAction::class)->setName('current');
       ....
   });
   $group->group('/group', function (Group $group) {
       $group->get('', GroupAction::class)->setName('group');
       $group->get('/section/{id}', GroupSectionAction::class)->setName('groupSection');
   });
   $group->get('/links', LinksAction::class)->setName('links');
....
});

$app->group('/v2', function (Group $group) {
    $group->redirect('/user/current', '/api/v1/user/current', 302);
    $group->group('/group', function (Group $group) {
        $group->redirect('', '/api/v1/group', 302);
        $group->redirect('/section/{id}', '/api/v1/group/section/{id}', 302);
    });
    $group->redirect('/links', '/api/v1/links', 302);
....
});

GET /api/v2/links - work correctly
POST /api/v2/user/current - 405 NOT ALLOWED
GET /api/v2/group - work correctly
GET /api/v2/group/section/15 - return org.apache.http.client.ClientProtocolException (problem in {id} I think)

POST /api/v2/user/current - 405 NOT ALLOWED

This is the correct behavior, because a redirect 302 from
/api/v2/user/current to /api/v1/user/current
is a GET and not a POST request.

In Slim v4 the App::subRequest() method has been removed. You can perform sub-requests via $app->handle($request) from within a route callable.

Example (not tested). This example callable could also be a Action class.

use use Psr\Http\Message\ServerRequestInterface;

// ...

$app->group(
    '/v2',
    function (Group $group) {
        // Internal forward / sub-request 
        $group->post(
            'user/current',
            function (ServerRequestInterface $request) use ($app) {
                $request = $request->withUri($request->getUri()->withPath('/v1/user/current'));
                return $app->handle($request->withMethod('POST'));
            }
        );
        // ...
    }
);
1 Like