I have this code, but it's very verbose. How Can I write that shorter?
Route::get('/transaction/index', 'TransacaoController#index');
Route::get('/transaction/test1', 'TransacaoController#test1');
Route::get('/transaction/test2', 'TransacaoController#test2');
Route::get('/transaction/test3', 'TransacaoController#test3');
Route::get('/transaction/test4', 'TransacaoController#test4');
Not sure if you're talking about the Route Prefixes in Laravel.
Route Prefixes
The prefix method may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:
Route::prefix('admin')->group(function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
});
Extracted from https://laravel.com/docs/5.7/routing
It might depends on how you prefer organize your infrastructure. Writing less not always is synonym of order.
You can use group() to apply middleware or prefixes to your routes:
Route::group(['middleware' => ['custom'], 'prefix' => 'transaction'], function(){
Route::get('/index', 'TransacaoController#index');
Route::get('/test1', 'TransacaoController#test1');
Route::get('/test2', 'TransacaoController#test2');
Route::get('/test3', 'TransacaoController#test3');
Route::get('/test4', 'TransacaoController#test4');
});
Now, there is another option (does not recommended). You can use a unique route making the separation of your logic at controller level:
Route::get('/transaction/{action}', 'TransacaoController#action');
function action($action){
if ($action == 'index'){
// ...
}
}
Related
Hello i'm new to laravel and im building my first api.
I have several routes that have the same prefix and i was wondering if its possible to group them under one route group and switch the last part of the uri to match the controller i need
Here is a example
main prefix: 'tenant'
possible routes: 'tenant/email_template' , 'tenant/review' , 'tenant/static_metas'
the routing that i want to achieve its something like this
Route::group(['prefix' => 'tenant/{entity}' , 'middleware' => 'auth'], function($router){
Route::post('{entity}/create', '{entity}Controller#create)->name({entity}.create);
});
Where the entity stand for the last part of the uri , if i give 'tenant/static_metas' i want to take the last part of the uri 'static_metas' and bind it to a create method calling the static_meta controller and its create method.
The reason behind this its to avoid rewriting the CRUD routes n-times changing only the controller and the uri.
Thank you
You can definitely do that, just use for loop.
And also the preferred group syntax is to separate prefix and middleware part into its own function with group having only closure.
$entities = ['email_template', 'review', 'static_metas'];
foreach($entities as $entity) {
Route::prefix("tenant/{$entity}")
->middleware('auth')
->group(function($router) use ($entity) {
$studEntity = \Str::studly($entity);
Route::post("{$entity}/create", "{$studEntity}Controller#create")
->name("{$entity}.create");
});
}
Also you should use Resource controller for consistent CRUD operations. https://laravel.com/docs/8.x/controllers#resource-controllers
I am looking to implement a whitelabel solution to my platform and need to implement wildcard subdomains for or system, the only issue is our system sits on a subdomain its self. So I need to filter out anything that comes to a specific subdomain.
// *.website.co.uk
Route::group(['domain' => '{element}.website.co.uk'], function() {
Route::get('/', function ($element) {
dd($element);
});
});
// my.website.co.uk
Route::get('/', 'PagesController#getLogin');
Route::post('/', 'PagesController#postLogin');
However using the code above I get the error:
Undefined variable: element
How would I avoid this error?
A good way is to exclude 'my' using a pattern. Put this code at the top of your routes file:
Route::pattern('element', '(?!^my$)');
Alternatively, that can go in the boot() section of your RouteSericeProvider. To give you a working solution, your code becomes the following (you can tidy up later!)
Route::pattern('element', '(?!^my$)');
Route::group(['domain' => '{element}.website.co.uk'], function() {
Route::get('/', 'PagesController#getLogin');
Route::post('/', 'PagesController#postLogin');
});
An alternative way is to match the 'my' route before matching the {element} route. However, while many do this I think it might be harder to maintain if the ordering of routes isn't clearly explained in the comments.
I'm fairly new to Laravel, so this question may obvious to some.
In the case of running checks per HTTP request, for example User Authentication. Is there a better, more efficient or simple correct way to run these checks. From my initial research it would seem that this could be accomplished using either MiddleWare, eg.
public function __construct()
{
$this->middleware('auth');
}
It also seems like it would be possible using routing groups, eg.
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Is there any benefits of doing this either of these two ways? Apart from the obvious benefit of not having to put $this->middleware('auth'); in every controller auth would need to be checked.
Thanks
Edit..
After taking on your advice I attempted to utilities the route grouping to control my Auth MiddleWare. But this has seemed to have broken my site.
Route::group(['middleware' => 'auth'], function () {
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get ( '/redirect/{provider}', 'SocialAuthController#redirect' );
Route::get ( '/callback/{provider}', 'SocialAuthController#callback' );
});
Am I missing something obvious?
You are almost there, just remove the Route::auth():
Route::group(['middleware' => 'auth'], function () {
Route::get('/home', 'HomeController#index');
//add more Routes here
});
The suggested options did not work for me but when I checked the laravel documentation, I found this:
Route::middleware(['web'])->group(function () {
//Your routes here
});
It works for me. Laravel 8.*
There is no real difference, personally i use groups for the standard middleware and put exceptions in the construct
Using Route group is easy for maintenance/modification , other wise you will have to remember each controller where you are using certain middle ware, of course this not a concern in a small medium sized application, but this will be hard in a large application where is lots of controller and references to middle ware.
I am building a RESTful API using Laravel 5.1.
The default route would be api. The user is allowed to create a url service using as many as parameters as she wants let's say .../api/p1/p2/.../pn.
How do I make a single route to point to a single Controller, so the service will be handled in a single controller?
Note : At first the application just needs to know whether the service exists or not by comparing the url with stored service in the database. As for the service itself, it can be queried into the database later.
I read that we can use * in Laravel 4, how about Laravel 5.1 ?
I have tried :
Route::resource('/api/*', 'APIServiceController'); but it does not work for unlimited parameters
or is it possible to do it like this
Route::group(['prefix' => 'api'], function () {
//what should I put in the closure, how can I redirect it to a single controller
});
Write your route as below:-
Route::group(['prefix' => 'api'], function () {
// this route will basically catch everything that starts with api/routeName
Route::get('routeName/{params?}', function($params= null){
return $params;
})->where('params', '(.*)');
});
Redirect to controller,
Route::group(['prefix' => 'api'], function () {
Route::get('routeName/{params?}', 'YourController#action')->where('params', '(.*)');
});
If you want to make routeName dynamic then just write it in curly bracket as below:-
Route::get('{routeName}/{params?}', 'YourController#action')->where('params', '(.*)');
Hope it will help you :-)
You can try this trick
Route::get('{pageLink}/{otherParams?}', 'IndexController#get')->where('otherParams', '(.*)');
You should put it on the end of routes.php file as it is like a 'catch all' route.
class IndexController extends BaseController {
public function get($pageLink, $otherParams = null)
{
if($otherParams)
{
$otherParams = explode('/', $otherParams);
}
}
}
I would like to create a dynamic route that allows multiple segments.
example.com/segment1
example.com/segment1/segment2/
example.com/segment1/segment2/segment3
Using this:
Route::get('{slug}', 'PagesController#index');
Gives me my first dynamic segment and of course I could do this:
Route::get('{slug1}/{slug2}', 'PagesController#index');
and so on but I'm sure there's a better way to do this.
I believe one complication when using Route::get('{slug1}/{slug2}', 'PagesController#index'); would be handling all possible inputs so segment1/segment2/ and also foo/bar/. You would probably end up with lots of unnecessary logic.
This may not be the best solution but I believe groups would work well for what you are trying to accomplish.
Route::group(array('prefix' => 'segment1'), function() {
Route::get('/', 'ControllerOne#index');
Route::group(array('prefix' => 'segment2'), function() {
Route::get('/', 'ControllerTwo#index);
Route::get('/segment3', 'ControllerThree#index');
});
});
Maybe a little messy when only dealing with three examples but it could end up being beneficial and provide a nicer hierarchy to work with.
This also has the benefit for using before and after filters. Like for all segment2 endpoints if you want to perform some filter, instead of adding the filter to all the individual endpoints you can just add it to the group!
Route::group(array('before' => 'someFilter', 'prefix' => 'segment2'), function() {
// ... ...
});