I have been using Laravel since version 3 and have also routed each URL I created to routes.php. However, I have seen some projects that don't use routes.php at all but still have URLs (of course). An example is Octobercms. So, my question is how is that even possible? I see zero indication of routing the way Laravel states in their doucmentation
When you look at a conventional routes.php you see a lot of Route::get() Route::resource() etc...
Those calls register the routes through the Route Facade. Now the thing is, you can register your routes everywhere you want (Route has to be accessible and it has to be "early" enough)
For example, if you're developing a package that only has one or two routes, you might want to do that in the boot function of your service provider.
But what Laravel does with the routes.php, it simply includes it with require
vendor/laravel/framework/src/Illuminate/Foundation/start.php
$routes = $app['path'].'/routes.php';
if (file_exists($routes)) require $routes;
Related
I'm new to Laravel and I am handed an existing application that is composed of two parts:
1 - An admin backend built on Laravel and uses Vueify
2 - The frontend website built on next.js and uses react components
The admin part communicates with Laravel using the "web routes" but also uses the "api routes" as well since the vue components make AJAX requests using those "api routes".
I am now tasked with "connecting" the frontend part to the laravel app. The frontend part will be using AJAX as well to communicate with laravel but I was told I should not use the same "api route" that is used by the admin backend because that has a lot more privileges that should not be accessible by the frontend. Basically it's a security risk and that I should somehow separate the two.
I'm not actually sure which term to use.. I initially thought it was called "channel" but I see that channel is one of the 4 "ways" of connecting to laravel (the other 3 being web, api and console). So I think routes is the term to use and forgive me for the double-quotes.
I have made a simple diagram to show the structure I mean. What I need to know is is there a way to create a second api route that would be used exclusively by the frontend and would include only a limited set of priviledges. I imagine something like /frontapi/ or /webapi/ as opposed to /api/ which is used now by the backend.
Thanks a lot for your help and please correct me if I am using wrong terminology.
EDIT
Thank you all for answering the part regarding separating the route prefix and the api route files.
One part of the question that I realized late that I hadn't made clear was the importance of separating the API Keys for both APIs since I think that is the main security issue and what would really make then two individual API "Channels or ways". I think that is one reason why I was confusing about the terminology because "way" sounded to me more separate that just a "route". I've also edited the question to reflect that. Thank you again for taking the time to help.
You can decompose routes in as many files as you want, you can also give each file its own prefix (like how api.php routes start with /api)
The modification need to be done in App\Providers\RouteServiceProvider
//in map() add $this->mapApiTwoRoutes()
public function map()
{
$this->mapApiRoutes();
$this->mapApiTwoRoutes();//<---this one
$this->mapWebRoutes();
}
//now add the method mapApiTwoRoutes
protected function mapApiTwoRoutes()
{
Route::prefix('api2')//<-- prefix in the url
->middleware('api')//<-- api middleware (throttle and such check App\Http\Kernal.php)
->namespace('App\Http\Controllers') //<-- you can modify the namespace of the controllers
->group(base_path('routes/apiTwo.php'));//<-- file containing the routes
}
And that's it.
You need to define a new route file, firstly add a new entry $this->mapApi2Routes(); in the map() function in app\Providers\RouteServiceProvider.
Then add a new function in that file, basically copying the mapApiRoutes() function, call it mapApi2Routes(). You can use different middleware etc. for the new file.
The last step would be adding a new file api2.php in the routes folder.
I use the Laravel 3 and I'm start a project using Laravel 5.1, a lot of things changes, include some way that I use to make my routes.
I like to implemente my routes using my controllers, like the code below:
Route::controller("Search");
Route::controller("Contact");
Route::controller("Login");
Route::get('/', "Inicio#index");
But it's not works in Laravel 5.1, someone knows if this way changes or not exists more?
Thank you.
You can use Route::resource() method, the first parameter will be the URL prefix and 2nd will be the controller name, like this:
Route::resource('admin-panel', 'AdminController');
Now, say if your controller have a method named login, the URL generated will be admin-panel/login. There's also an optional 3rd parameter, check laravel docs for details.
I was contributing to a project that now has a routes.php file with like over 800 lines of routes. I was wondering if Laravel had a specific convention or a way to organize this so it doesn't have to have all routes in one large confusing file?
Separate routes for large applications into multiple smaller route partial files that are automatically loaded at runtime.
Also you can
Group routes
Route namespaces
Route prefixes
Useful examples
partial routes
split routes in different parts
organize routes
explained route using
break routes
Also i can recommend route caching for performance
Route caching tutorial
The best ways are groups and don't list every single route but use controller routes.
http://laravel.com/docs/4.2/routing#route-groups
http://laravel.com/docs/4.2/controllers#implicit-controllers
If this doesn't help it's possible to split this file into multiple files, for example: routes/users.php, routes/posts.php and so on, and include these into the original routes.php
Also it would help to put some routes in different files.
For example, you could create a folder called routes in your app folder, then add files in that folder. I usually have one file for authentication routes, then other files for the high level navigation items of the site.
don't forget to require those files in app/start/global.php
/*
|-------------------------------------------------------------------------
| in app/start/global.php
|-------------------------------------------------------------------------
|
*/
require app_path( 'routes/auth.php'); // Auth routes
require app_path( 'routes/articles.php'); // Article routes
maybe you should also consider using controller along side this technique to further slim you routes
I'm coming From CodeIgniter to Laravel.
So, is a bad idea using automatic routes to all of controllers?
Route::controller(Controller::detect());
Should I use this instead creating routes in routes.php?
Yes this is bad.
Controller::detect() is actually not present in Laravel 4 because it is a bit broken.
detect() will go through your filesystem and return controller files, but this is a bad idea because the order you define your routes matters. If you have any nested controllers you will find this breaking very easily.
detect() will also return files in a different order depending on the file system, so this leads to a lot of unpredictability.
I would argue that you should define all your routes any ways, it is a lot easier to read and debug.
One of interesting things about Laravel that CI does not have is that for certain pages, you can route directly to the view without needing a controller at all. Think about static pages like 'About Us'. CodeIgniter would need you to set up a controller + view for that, even though the controller will do barely anything. In case of Laravel, you can route directly to a view in this case.
Setting up routes manually will allow you to set these short-circuited routes.
Automatic detection is a bad idea.
You can use routes or use Route::controller('mycontroller') or and array of controllers like Route::controller(array('mycontroller', mycontroller2');
Then you get the benefit, without the autodetect.
in laravel 4 :
you can use Restful Controller like documentation http://laravel.com/docs/controllers#restful-controllers
But
Route::controller() must take two parameters as minimum requirement
first parameter stands for URL respond to ,and second parameter is name of controller
also
you can write third parameter into Route::controller() is an array with names of actions (name of action with HTTP verb )and routes names for this actions
ex:
Route::controller('users','UsersController',array(
'getUsers' =>"listUsers" ,
));
route name for getUsers action is listUsers
Below is a good example to follow for CRUD and general purpose routing
type php arisan controller:make SampleController
edit routes.php and add
Route::resource('sample', 'SampleController');
Then type
php artisan routes to show the newly created routes
I have my own routing rules in routes.php, defined for all the pages that should be accessible via URL, such as mywebsite/blog/ and mywebsite/blog/category/category-name, i.e. the structure of my whole website is covered by my custom routes.
Now, I have a lot of elements that make use of requestAction, such as
$websiteabstract = $this -> requestAction(array(
'controller' => 'assets',
'action' => 'displayHomeAbstract'
));
This gives me an error Error: Controller could not be found, probably because I have not defined a route for /assets/displayHomeAbstract. But why do I have to define a custom route for that, when I explicitly state the name of the controller and the action? Shouldn't that bypass the routing altogether?
Either I have not understand Routing at all. Or do I really have to define ALL the possible routes (even those that are only used by requestAction) in my routes.php? I mean, I don't want to allow users to directly access mywebsite/assets/displayHomeAbstract anyway, only via an Element.
Thank you
EDIT: Here is my routes.php http://pastebin.com/aAKBwNZJ
Please have a look at line 128, this is exactly what I do not want since /assets/displayHomeAbstract is ONLY accessed via requestAction.
EDIT: And this is the element, that makes the request: http://pastebin.com/0tK5dYJk
Okay, after extensive discussion with the devs in IRC, I think I understand this well enough to explain to you:
You do have to define your custom routes for your requestAction in this case. requestAction is emulating a full request. It dispatches a request as if accessed using the string url every time, even when the url provided is an array. The book is referring to how when you have a custom route defined in addition to using the default routes (the last line of routes.php), you can use array urls to be agnostic of those routes. However, these array urls rely on the default routes.php in the /lib/ folder and are used to construct a url string. If you're going to have a custom routing pattern, you have to construct the url strings on your own.
Note: the comments below were from earlier versions of this answer.
The key to your problem is understanding the scope of Cake's routing and how it work.
When you define a route in CakePHP, it isn't just used for mapping URLs to controllers. It's also used by the Router for things like generating link addresses and, in your case, mapping the path supplied to requestAction() to a controller. Behind the scenes, Cake is creating a URL string based on your parameters, and then passes it off to the Router to find the correct controller. Since no such route exists, it fails.
As a solution, I would actually recommend not using a controller for that logic. Depending on what it does, a component or a helper may be a better place.
Look at line 156. You commented out the line that loads CakePHP's default routes.