johannchopin
johannchopin

Reputation: 14844

Declare same route twice but expect different behaviour according to a middleware

I started creating a REST API using the lumen framework and wanted to set up a particular behaviour for my GET /user route. Behaviour is the following:

It seems logic to me to just write it like that in my web.php using a simple middleware:

<?php

$router->group(['middleware' => 'auth'], function () use ($router) {
    $router->get('/user/{id}',  [
        'uses' => 'UserController@getAllFields'
    ]);
});

$router->get('/user/{id}',  [
    'uses' => 'UserController@get'
]);

But for some reason, even if the middleware is correct, I always get the response of the second route declaration (that call get()). I precise that if I remove the second route declaration, the one in the middleware work as expected.

Have someone an idea how I can achieve something similar that work?

Upvotes: 3

Views: 546

Answers (2)

chojnicki
chojnicki

Reputation: 3614

Router will check if your request matches to any declared route. Middleware will run AFTER that match, so You cannot just return to router and try to find another match.

To fallow Laravel and Routes pattern - You should have single route that will point to method inside controller. Then inside that You can check if user is logged or not and execute getAllFields() from that controller. It will be not much to rewrite since You are currently using UserController in both routes anyway.

web.php

$router->get('/user/{id}', 'UserController@get');

UserController.php

public function get()
{
   return auth()->check() ? YourMethodForLogged() : YourMethodForNotLogged();
}

Or if there is not much logic You can keep this in single method.

Also it is good idea to fallow Laravels REST standards (so use show instead of get, "users" instead of "user" etc - read more https://laravel.com/docs/7.x/controllers)

web.php

$router->get('/users/{user}', 'UserController@show');

UserController.php

public function show(User $user)
{
   if (auth()->check()) {
      //
   } else {
      //
   }
}

To summary - for your needs use Auth inside controller instead of middleware. To check if user is logged You can use Facade Auth::check() or helper auth()->check(), or opposite Auth::guest() or auth()->guest().

If you are actually using Lumen instead of full Laravel then there is not auth helper by default (You can make own or use package like lumen-helpers) or just keep it simple and use just Facades instead (if You have then enabled in Lumen).

Read more https://laravel.com/docs/7.x/authentication and https://lumen.laravel.com/docs/7.x/authentication

Upvotes: 3

Robo Robok
Robo Robok

Reputation: 22683

This pattern is against the idea of Laravel's routing. Each route should be defined once.

You can define your route without auth middleware enabled and then define your logic in the controller.

Upvotes: 0

Related Questions