Search code examples
phplaravellumen

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:

  • If the request come from an authenticated user (using auth middleware), the method getAllFields from UserController is called and return all the data from the user
  • If it's not the case, the method get from UserController is called and return some of the data from the user

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?


Solution

  • 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