framework: php artisan make:auth conflicts with route:cache 'Unable to prepare route [api/user] for serialization. Uses Closure.'

  • Laravel Version: 5.5.20
  • PHP Version: 7.0.22
  • Database Driver & Version: mysql 5.7

Description:

I use ‘php artisan make:auth’ command to scaffold routes and views for authentication, however when I run ‘php artisan route:cache’, an error will occur:

[LogicException] Unable to prepare route [api/user] for serialization. Uses Closure.

Steps To Reproduce:

  1. create a new project with “laravel/installer”
  2. run ‘php artisan make:auth’
  3. run ‘php artisan route:cache’

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 22 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@themsaid Please, stop throwing responsibility on the others. This is definitely a bug. Laravel offers predefined code in routes/api.php

Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); });

which is unabled to be processed by:

php artisan route:cache

This definitely should be fixed.

Can you check your routes/web.php and routes/api.php for closures.

Laravel comes with default route closure in routes/web.php:

Route::get('/', function () {
    return view('welcome');
});

and routes/api.php

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

if you remove that then try again it should work I reckon.

Please ask on the forums, this repo is for bug reporting only. You can use https://laracasts.com/discuss or https://laravel.io/forum which are forums with a very large community of developers helping each other.

Why is this closed? This is an obvious bug.

Yeah. You’re right is written in documentation. But that isn’t the problem. Problem is, that some Laravel developer written some code which can’t be compiled if someone wants to cache routes.

If Laravel contains code which can’t be compiled, it’s bug and should be fixed.

The “auth” method has no effect on route caching. The method (below) only adds controller based routes, which are perfectly cacheable.

    public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');
        // Registration Routes...
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
        // Password Reset Routes...
        $this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
        $this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
        $this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
        $this->post('password/reset', 'Auth\ResetPasswordController@reset');
    }

The issue is that in the laravel/laravel skeleton app, there are a couple of sample Closure routes included in the api and web routes files. These routes are present for example purposes. Route caching is a documented optional feature. This documentation makes it clear that if you want to cache your routes, you’ll need to be sure to use the controller based approach for it to work.

There are many features in Laravel that don’t just “work” out-of-the-box. You can change your “session”, “cache” and/or “queue” handling to use redis. However if you just change this to redis and expect it to just work, you’ll be disappointed, as there are other libraries that need to be pulled in first. I just don’t believe that we can expect everything provided by the framework to just work. Sometimes you have to do a little research and make sure everything is set up correctly first.

Straight from the documentation:

IF your application is EXCLUSIVELY using controller based routes, you should take advantage of Laravel’s route cache. Closure based routes cannot be cached. To use route caching, you must convert any Closure routes to controller classes.

Had this error Unable to prepare route [api/user] for serialization. Uses Closure. Commented this line in routes/api.php:

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Executed php artisan route:cache and it worked. I agree with @xkovacikm it must be fixed.

@xkovacikm feel free to open a PR

also having this issue.