I've two route controllers within a route group:
Route::group(array('before' => 'auth'), function()
{
Route::controller('dashboard/', 'DashboardController');
Route::controller('dashboard/profile', 'DashboardProfileController');
});
That works until I add prefix key to the array:
Route::group(array('prefix' => 'dashboard', 'before' => 'auth'), function()
{
Route::controller('/', 'DashboardController');
Route::controller('/profile', 'DashboardProfileController');
});
It's weird as the first route controller works since I can access localhost/dashboard but the second fails on localhost/dashboard/profile and or localhost/dashboard/profile/edit
What's wrong here?!
It seems both of them route to one location, therefore the longest one should go first because it is interpreted as argument.
Route::group(array('prefix' => 'dashboard', 'before' => 'auth'), function()
{
Route::controller('/profile', 'DashboardProfileController');
Route::controller('/', 'DashboardController');
});
Related
I know this is a basic laravel question but don't know how do it. How can I add one route to 2 different middleware (auth) without having to duplicate it?
// =admin
Route::group(['middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
// =cashier
Route::group(['middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
I have this route and I don't want to repeat calling this per auth middleware: Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
You can't have two routes with the same url.
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
This route is inside both groups and since the url they will produce will be the same, only the second will remain.
Route::group(['middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
//Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
// this route will be ignored because the other one has the same url
});
Route::group(['middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
If you want Laravel to handle these two routes differently, you have to add a prefix:
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['auth']], function() {
Route::get('/dashboard', 'App\Http\Controllers\DashboardController#index')->name('dashboard');
//Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
// this route will be ignored because the other one has the same url
});
Route::group(['prefix' => 'cashier', 'as' => 'cashier.', 'middleware' => ['auth', 'role:cashier']], function() {
Route::get('/dashboard/cashier/profile', 'App\Http\Controllers\DashboardController#showCashierProfile')->name('dashboard.cashier.profile');
Route::get('make-a-sale', [PurchasesController::class, 'index'])->name('make-a-sale.index');
});
This way, when the url will be prefixed with admin, the first route will be called (without the role:cashier middleware).
Notice that I added a route name prefix ('as' => 'admin.' / 'as' => 'cashier.') so you can call each one by name, using:
route('admin.make-a-sale.index'); // admin/make-a-sale
//or
route('cashier.make-a-sale.index'); // cashier/make-a-sale
Just to add, if someone wants to fix the Laravel blade error below whenever you clear your browser cache and was automatically logout:
*Attempt to read property "name" ...*
You need to add all your routes inside the:
Route::group(['middleware' => ['auth']], function () {
// routes here
});
This will redirect you to login once that happens.
I'm creating an API that is available only via POST. I'm planning to have more than one version of the API, so the current one uses v1 as part of the URL.
Now, in case an API call is made via GET, PUT or DELETE I would like to return a Fail response. For this I'm using Route::match(), which works perfectly fine in the code below:
Route::group(['namespace'=>'API', 'prefix' => 'api/v1', 'middleware' => 'api.v1'], function() {
Route::match(['get', 'put', 'delete'], '*', function () {
return Response::json(array(
'status' => 'Fail',
'message' => 'Wrong HTTP verb used for the API call. Please use POST.'
));
});
// User
Route::post('user/create', array('uses' => 'APIv1#createUser'));
Route::post('user/read', array('uses' => 'APIv1#readUser'));
// other calls
// University
Route::post('university/create', array('uses' => 'APIv1#createUniversity'));
Route::post('university/read', array('uses' => 'APIv1#readUniversity'));
// other calls...
});
However, I noticed that I could group the routes even more, to separate the API version and calls to specific entities, like user and university:
Route::group(['namespace'=>'API', 'prefix' => 'api'], function() {
Route::match(['get', 'put', 'delete'], '*', function () {
return Response::json(array(
'status' => 'Fail',
'message' => 'Wrong HTTP verb used for the API call. Please use POST.'
));
});
/**
* v.1
*/
Route::group(['prefix' => 'v1', 'middleware' => 'api.v1'], function() {
// User
Route::group(['prefix' => 'user'], function() {
Route::post('create', array('uses' => 'APIv1#createUser'));
Route::post('read', array('uses' => 'APIv1#readUser'));
});
// University
Route::group(['prefix' => 'university'], function() {
Route::post('create', array('uses' => 'APIv1#createUniversity'));
Route::post('read/synonym', array('uses' => 'APIv1#readUniversity'));
});
});
});
The Route::match() in the code above does not work. When I try to access any API call with e.g. GET, the matching is ignored and I get MethodNotAllowedHttpException.
Can I get the second routes structure to work with Route::match() again? I tried to put it literally everywhere in the groups already. Putting the Route::match() outside of the hole structure and setting path to 'api/v1/*' does dot work either.
If you use the post() function you don't need to deny manualy other verb.
What you can do is to create a listener for the MethodNotAllowedHttpException and display what you want. Or you can also use any() function at the end of your route's group to handle all route that is not defined.
i have multiple namespaces in my application namely FrontEnd namespace and BackEnd namespace, now in my routes file i would like to know the correct way to direct each route to a namespace.
This is what i have at the moment:
Route::group(['namespace' => 'FrontEnd'], function()
{
Route::group(array('prefix' => '/api/v1/'), function()
{
});
});
Now the above works alright (at least when i tried it) but just to make sure i was doing the right thing i wanted to ask so i don't experience and problems in the future.
I would like to know if this is the correct way of going about it instead:
Route::group(array('prefix' => '/api/v1/'), function()
{
Route::group(['namespace' => 'FrontEnd'], function()
{
});
});
Or does it not matter at all whichever way i decide to go?
you can pass all your option for route group in attribute array like this
Route::group(array('middleware' => 'youemiddleware', 'prefix' => 'yourprefixes', 'namespace' => 'yournamespaces', 'domain' => 'subdomains'), function()
{
// your routes
});
I see no preference one over the other.
How about this?
Route::group(array('prefix' => '/api/v1/', 'namespace' => 'FrontEnd'), function()
{
// code goes here
});
How do you have a the start of the route to have admin at the begining of the route like '/admin/attributes/1/edit in the routes group collection instead of just /attributes/1/edit
Route::group(array('before' => 'Admin'), function() {
Route::resource('attributes', 'AttributesController');
Route::resource('brands', 'BrandsController');
Route::resource('products', 'ProductsController');
Route::resource('tags', 'TagsController');
Route::resource('roles', 'RolesController');
Route::resource('suppliers', 'SuppliersController');
});
You need to use a prefix
Route::group(array('prefix' => 'admin'), function()
{
// routes here
});
See Laravel Documentation
I'm experiencing routing confusion in laravel 4.
Route::group(['prefix' => 'myProfile', 'before' => 'auth|inGroup:Model|isMe'], function()
{
Route::get('/{username}', function(){
echo 'hello';
});
});
Route::get('/{username}', [
'as' => 'show-profile',
'uses' => 'ProfileController#index'
]);
When i write to address bar domain.app/myProfile it runs second route and runs ProfileController#index...
Thanks.
Looks like correct behaviour. To access first route you would have to type something like domain.app/myProfile/FooUser. You didn't specify / route in myProfile route group, so it cannot match it and uses second one.
Breaking down your routes:
1)
Route::get('/{username}', [
'as' => 'show-profile',
'uses' => 'ProfileController#index'
]);
Use /example URI to access the above route.
2)
Route::group(['prefix' => 'myProfile', 'before' =>'auth|inGroup:Model|isMe'], function()
{
Route::get('/{username}', function(){
echo 'hello';
});
});
Use /myProfile/example URI to access the above route.
Your application is working as expected.