How to call ApiResource with middleware in my routes? - laravel

When I use middleware like below, no problem:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
But if I try to use it with apiResources, like below:
Route::apiResources([
'user' => 'API\UserController',
'posts' => 'API\PostController'
])->middleware('auth:api');
Then I get an error message:
php artisan route:list
BadMethodCallException
Method Illuminate\Routing\RouteRegistrar::apiResources does not
exist.
What is the correct way to call ApiResource with middleware in routes/api.php ?

I don't believe you can add any middleware's to the apiResources, what you could do instead is nest them inside a route group that applies them
Route::group(['middleware' => 'auth:api'], function () {
Route::apiResources([
'user' => 'API\UserController',
'posts' => 'API\PostController'
]);
});
This would also allow you to shorten the controller definitions with the namespace option:
Route::group(['middleware' => 'auth:api', 'namespace' => 'API'], function () {
Route::apiResources([
'user' => 'UserController',
'posts' => 'PostController'
]);
});

Related

Which is valid syntax for route of ads/ad_locations editor?

In my Laravel 8 app I want to make route of ads/ad_locations editor
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
...
Route::group(['prefix' => 'ads'], function ($router) {
...
Route::resource(
'/{ad_id}/ad_locations',
AdLocationController::class
)->name('admin.ads.ad_locations');
But I got error clearing routes :
$ php artisan route:cache
ArgumentCountError
Too few arguments to function Illuminate\Routing\PendingResourceRegistration::name(), 1 passed in /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/routes/web.php on line 112 and exactly 2 expected
at vendor/laravel/framework/src/Illuminate/Routing/PendingResourceRegistration.php:110
106▕ * #param string $method
107▕ * #param string $name
108▕ * #return \Illuminate\Routing\PendingResourceRegistration
109▕ */
➜ 110▕ public function name($method, $name)
111▕ {
112▕ $this->options['names'][$method] = $name;
113▕
114▕ return $this;
1 routes/web.php:112
Illuminate\Routing\PendingResourceRegistration::name()
+3 vendor frames
5 routes/web.php:119
Illuminate\Support\Facades\Facade::__callStatic()
Which syntax is valid and how to ref in in blade file ?
MODIFIED BLOCK:
I modified in routes/web.php :
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
'edit' => 'admin.ads.ad_locations.edit',
]
]);
and run command with success :
php artisan route:cache
But in blade file using it :
<a class="btn btn-primary" href="{{ route('admin.ads.ad_locations.edit',[$ad_id, $nextAdLocation['id']]) }}">
{!! showAppIcon('edit') !!} Edit
</a>
I got error :
(Symfony\\Component\\Routing\\Exception\\RouteNotFoundException(code: 0): Route [admin.ads.ad_locations.edit] not defined. at /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php:429)
[stacktrace]
Which way is correct ?
Thanks!
Function name() doesn't work with route::resource, because it's a collection of routes, it should be used with individual routes like:
Route::get('user/create', [UserController::class, 'create'])->name('user.create');
You can either supply a "names" array as the third parameter (options) parameter to the resource route, like:
Route::resource('user', UserController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
// etc...
]
]);
or, you can use with as keyword, like the one you have used in your route:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.ads.ad_locations.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class);
});
});
In the above snippet, I have used your complete route "admin.ads.ad_locations" name in "as" attribute's value. But, this last one will be treated as prefix for every single route like this:
admin.ads.ad_locations.{ad_id}.store
admin.ads.ad_locations.{ad_id}.create
...
You can also, use function names() like below:
Route::resource('/{ad_id}/ad_locations', PhotoController::class)->names([
'create' => 'admin.ads.ad_locations.build'
'show' => 'admin.ads.ad_locations.view'
]);
Answer For Rectified Section of the Question:
Because you are using "as" attribute in your route as well, the route names generated for you will be:
admin.admin.ads.ad_locations.store
admin.admin.ads.ad_locations.create
admin.admin.ads.ad_locations.create
You can either remove the as attribute from your route, like:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
'edit' => 'admin.ads.ad_locations.edit',
]
]);
});
});
or, you can avoid using "admin." in your routes names, like:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'ads.ad_locations.index',
'store' => 'ads.ad_locations.store',
'edit' => 'ads.ad_locations.edit',
]
]);
});
});

How to fix Class not found error while making POST request?

In api.php I've described some routes. GET method works. Can't tell the same about POST method.
<?php
use Illuminate\Http\Request;
use App\UserUnfo;
Route::middleware('auth:api')->get('/user', function (Request $request)
{
return $request->user();
});
Route::get('/person', function() {
$person = [
'ip' => '127.0.0.1',
'name' => 'me'
];
return $person;
});
Route::post('/person', function(Request $request) {
$userInfo = UserInfo::create([
'name' => $request->input('name'),
'ip' => $request->input('ip')
]);
return $userInfo;
});
In web.php
Route::get('/home', 'HomeController#index')->name('home');
The error I've got
Class 'UserInfo' not found
You're using the wrong model it's spell mistake.
use App\UserUnfo;
To
use App\UserInfo;

Laravel route [login] not defined inside a file

I am building a modular application in laravel. I created a User module and here is the routes:
<?php
Route::group(['middleware' => 'web', 'namespace' => 'Modules\User\Http\Controllers'], function()
{
Route::get('/', 'UserController#index');
Route::get('login', 'LoginController#showLoginForm')->name('login');
Route::post('login', 'LoginController#login');
Route::post('logout', 'LoginController#logout')->name('logout');
});
Route::group(['middleware' => 'admin', 'prefix' => 'user', 'namespace' => 'Modules\User\Http\Controllers'], function()
{
Route::get('register', 'RegisterController#showRegistrationForm')->name('register');
Route::post('register', 'RegisterController#register');
});
The route('login') statement returns the url to login page and it works well. Inside the config.php I need to access this function as follows
<?php
return [
'name' => 'User',
'menu' => [
'weight' => 1,
'item' => [
'Login' => [route('login'), 'guest'],
'Register' => [route('register'), 'guest'],
]
]
];
Inside this file the error Route [login] not defined. is reported. Why is this undefined in there?
I also tried adding the following line
namespace Modules\User\Http\Controllers;
But it still not working
thanks

Laravel add custom middleware to route group

in my web application i have admin panel and i'm trying to make access to users that they have admin role by this code:
namespace App\Http\Middleware;
use Closure;
class CheckUserAdminRole
{
public function handle($request, Closure $next)
{
if (auth()->check()) {
if (auth()->check() && !auth()->user()->hasRole('admin')) {
auth()->logout();
return redirect(route('system.messages','userIsNotAdmin'));
}
}
return $next($request);
}
}
and in my routs i have this route group:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web'], 'prefix' => 'dashboard'], function () {
$this->group(['prefix' => 'administrator'], function () {
$this->get('panel', 'AdminController#index');
});
my kernel:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
...
\App\Http\Middleware\CheckUserAdminRole::class,
];
now when i add my middleware as CheckUserAdminRole to route group like with this code:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web','CheckUserAdminRole'], 'prefix' => 'dashboard'], function () {
i get this error:
Class CheckUserAdminRole does not exist
this codes couldn't resolve my problem:
php artisan route:clear
php artisan cache:clear
php artisan config:clear
composer dump-autoload
Instead of registering your middleware in the $middleware array, you should register it in $routeMiddleware like so:
protected $routeMiddleware = [
...
'checkAdmin' => \App\Http\Middleware\CheckUserAdminRole::class,
];
Note: registering a middlware in the $middleware array results in it being executed for every request and therefore is not applicable on specific routes.
Then you can use it in your routes with the checkAdmin name:
Route::group(['namespace' => 'Dashboard', 'middleware' => ['auth:web','checkAdmin'], 'prefix' => 'dashboard'], function () {
Source
You can also use middleware and route group together easily like so:
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function()
{
//All the routes that belongs to the group goes here
Route::get('dashboard', function() {} );
});
Here's a simple fix without touching the Kernel file and taking advantage of the Policy. The accessAdmin is a function created inside Policy file.
Route::group(['namespace' => 'Dashboard', 'middleware' => 'can:accessAdmin, App\User', 'prefix' => 'dashboard'], function () {
$this->group(['prefix' => 'administrator'], function () {
$this->get('panel', 'AdminController#index');
});
You can try middleware with prefix and groups.
Route::middleware(['Auth'])->prefix('api/')->group(function() {
Route::group(['prefix' => 'review/'], function () {
Route::get('/', 'User\Controllers\Api\UserController#getUserReviews');
});
});
Hope its helps

Laravel admin/user route prefix approach

so I have to make this system for transport management. The user can log in create/update/edit all his trips. But the admin can do the same for all users. I have divided user and admin in to route prefixes:
Route::group(['prefix' => 'admin/', 'middleware' => ['auth','admin']], function(){
Route::resource('trips', 'TripsController',
array('except' => array('show')));}
Route::group(['prefix' => 'user/', 'middleware' => ['auth', 'user']], function(){
Route::resource('trips', 'TripsController',
array('except' => array('show')));
}
The problem is in every method of the TripController I have to pass route variable with the correct url (the admin request will have a 'admin' prefix, and the users will have 'user' prefix)
return View('trips.index', compact('users', 'route'));
The question is there a way to do this nicely or should I just pull the trips Route::resource out of the both groups so that it wouldn't have any groups? What is the correct approach here?
I use this approach:
Route::group(['namespace' => 'Admin', 'as' => 'admin::', 'prefix' => 'admin'], function() {
// For Other middlewares
Route::group(['middleware' => 'IsNotAuthenticated'], function(){
// "admin::login"
// http://localhost:8000/admin/login
Route::get('login', ['as' => 'login', 'uses' => 'AdminController#index']);
});
// For admin middlewares
Route::group(['middleware' => 'admin'], function(){
// "admin::admin.area.index"
// http://localhost:8000/admin/area/{area}
Route::resource('Area', 'AreaController');
// "admin::dashboard"
// http://localhost:8000/admin/
Route::get('/', ['as' => 'dashboard', 'uses' => 'AdminController#dashboard']);
});
});
Whenever I need to access url in blade templates I simply use route helper method.
// For resourceful routes
{{ route('admin::admin.city.index') }}
or
//For regular get/post routes
{{ route('admin::dashboard') }}
Or simply run artisan command to list route names.
php artisan route:list
I did it with this:
//Admin Group&NameSpace
Route::namespace('Admin')->prefix('admin')->group(function () {
Route::get('/dashboard', 'DashboardController#index')->name('dashboard')->middleware('auth');
});
Even you can customize the ->middleware('auth'); with a custom middleware role based.

Resources