Laravel Unable to prepare route [api/user] for serialization. Uses Closure - laravel

When I commenting all routes I getting this error.
Please say me, what are the closure routes? And why showing this error

A closure is an anonymous function which is used to define routes without an action:
Route::get('/test', function () {
return 'hello world';
});
The example above returns hello world when you call the route /test in your browser.
You can't cache routes that are referencing a closure.
There are two routes using closures in a default Laravel app: in the files routes/api.php and routes/web.php. Remove them or move them to a controller and you are able to cache your routes.
Here's an issue in the Laravel framework repository which is discussing this behaviour.

Related

Unable to prepare route[api/user] for serialisation. Uses Closure - Laravel

LogicException : Unable to prepare route [api/user] for serialization. Uses Closure.
at /var/www/html/dev_laravel/vendor/laravel/framework/src/Illuminate/Routing/Route.php:917
913| */
914| public function prepareForSerialization()
915| {
916| if ($this->action['uses'] instanceof Closure) {
> 917| throw new LogicException("Unable to prepare route [{$this->uri}] for serialization. Uses Closure.");
918| }
919|
920| $this->compileRoute();
921|
Exception trace:
1 Illuminate\Routing\Route::prepareForSerialization()
/var/www/html/dev_laravel/vendor/laravel/framework/src/Illuminate/Foundation/Console/RouteCacheCommand.php:62
2 Illuminate\Foundation\Console\RouteCacheCommand::handle()
/var/www/html/dev_laravel/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
When i trying to run the laravel command
php artisan route:cache
I try to find out the solution but not get the correct solution.
https://github.com/laravel/framework/issues/22034
Is this laravel bug still or fixed the bug?
I have the code on web.php file
Route::get('/', function () {
return view('welcome');
});
Route::resource('photos', 'PhotoController#index');
I'm Using Laravel 5.8. Just installed and migrated database. I'm beginner for laravel.
Can anyone let me know the correct solution?
Thanks in advance
It is not a bug. You can not use Closure based routes like that if you want to cache the routes. Direct any Closure based route to a Controller method instead and you will be fine. [You have one in web.php and the error is pointing out one in api.php]
The Closure based route you have in web.php could be replaced with:
Route::view('/', 'welcome');
This would direct it to a Controller that just handles returning view files.
The Closure based route in api.php should point to a Controller:
Route::middleware('auth:api')->get('user', 'SomeController#user');
Consider any routes that come with the laravel/laravel project as being functional but are there for demonstration purposes.
"Closure based routes cannot be cached. To use route caching, you must convert any Closure routes to controller classes."
Laravel 5.8 - Docs - Controllers - Route Caching
EDIT:
AS OF LARAVEL 8.X YOU CAN ALSO CACHE CLOSURE BASED ROUTES
When you run the command php artisan route:cache
Laravel will cache all your routes and store it in specified Cache Driver
Now Comming to your Error Message:
As the error Message Clearly Says that
Closure Routes can't be Cached
And even the Laravel Docs says that Route Caching
By Default Laravel Comes with Four routes files
And this will have 2 Closure based routes
Solution:
You can remove them if you no longer using that routes
Make a Controller and Move that to Controller
LogicException : Unable to prepare route [api/user]
Which means that
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
This Code in Your routes/api.php is causing the issue So
Route::middleware('auth:api')
->get('/user', 'SomeController#method');
Or you can remove that if not using that
You could not use specific method when you use resource for the routing.
You can use
Route::resource('photos', 'PhotoController');
Or
Route::get('photos', 'PhotoController#index');

Exclude conditional routes in Laravel

I'm building and application in Laravel and Vuejs where I'm having Laravel routes as below:
Route::get('/admin/{view?}', 'HomeController#admin')->where('view', '(.*)')->name('admin');
Route::get('/{view?}', 'HomeController#home')->where('view', '(.*)')->where('view', '!=', 'admin')->name('home');
I'm using Vue-router so I'm having routing in vuejs, and I'm using history mode. The problem is when I try to call /admin it generally calls HomeController#home method. even if I go deeper like /admin/dashboard it is calling the same home method. I want if admin prefix is being called then it should call HomeController#admin method.
its all okay for me please check this
Route::get('/admin/{view?}', function (){
dd('okay');
})->where('view', '(.*)')->name('admin');
Route::get('/{view?}', function(){
dd('okay1');
})->where('view', '(.*)')->name('home');
So try this
Route::get('/admin/{view?}', 'HomeController#admin')->where('view', '(.*)')->name('admin');
Route::get('/{view?}', 'HomeController#home')->where('view', '(.*)')->name('home');

Laravel Route, ->name method?

Laravel 5.5
which is the different doing (no get and post methods) on route defintion web.php file:
$this->get('login', 'Auth\LoginController#showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController#login');
regarding ->name('') method
Is required define that method? in which cases?
(sample taked from Auth Class definition laravel)
The idea of defining ->name() in routes is for easier code maintenance in the future, it's not mandatory.
Say for example you have few places which uses the route login, one fine day you update the route to user-login. You will have to find and update all the route being used, changing from url('login') to url('user-login').
If you have a route name defined, you will be using route('login'), when you update your route url, there's no need to update all the other files that you're using that route.

Vue SPA url not working with history mode enabled

I am creating a SPA using Vue js and it kind of works but I have one problem. With history mode enabled on Vue I can enter urls and go to that page using the Vue Router but when I try to login I get the literal page html. I know I can do something like auth\{vue?} but I would prefer if i didn't have to do that. I want to be able to always keep the url with no prefixes unless it is to an API request. So for example:
I have the root view:
Route::get('/{vue?}', function () {
return view('layouts.app');
})->where('vue', '[\/\w\.-]*');
and then I have the api requests:
Route::group(['prefix' => 'api'], function () {
Route::post('/login', 'Auth\\LoginController#login');
Route::post('/register', 'Auth\\RegisterController#register');
Route::get('/logout', 'Auth\\LoginController#logout');
});
but when I hit /api/login I get the return view data from /{vue?}.
I hope that makes sense and if so any help would be amazing, Thanks.
it is clearly explained here: https://kjamesy.london/work/laravel-53-vuejs-20-make-vuerouters-history-mode-play-nicely-with-laravels-routes
Short story: declare history mode to false in VueRouter and then on the Laravel side, whenever the $request->ajax() is false, the same route will always capture the request. So, we can safely define a catch-all route to redirect such traffic to the index() method of our resource controller:

Laravel 5.2 Session not passing

I have a simple success message on store to DB.
\Session::flash('info', 'Success! Words created');
now if I var_dump the session and return that, great.
As soon as I move to another view. Session info is gone!
I've tried all sorts, I'm on laravel 5.1.
looked into the middleware groups but i just get blank pages when adding routes in here..
This is a breaking problem with the 5.2 upgrade. What's happening is the middleware which is responsible for making that errors variable available to all your views is not being utilized because it was moved from the global middleware to the web middleware group.
There are two ways to fix this:
In your kernel.php file(app/Http/Kernel.php), you can move the middleware \Illuminate\View\Middleware\ShareErrorsFromSession::class back to the protected $middleware property.
Wrap all your web routes with a route group and apply the web middleware to them:
Route::group(['middleware' => 'web'], function() {
// Place all your web routes here...(Cut all `Route` which are define in `Route file`, paste here)
});

Resources