I'm trying to create a Symfony form with a ChoiceType field that contains all the routes currently available. This form has the purpose of adding these routes to a module in our backend. I've already created a Module and Route entity. These are used to render the correct navigation structure for the users working on a specific module.
I've used Router#getRouteCollection() inside the form controller, using this the routing cache will be rebuild on every request to the page.
I was thinking about a command that uses this method and adds all the routes to the database. However this means that every time a route is added, this command needs to be executed as well. This seems like a step too much for such a simple task.
What would be the best practice to load these routes inside the controller? And would it be possible to do this without:
Rebuilding the cache every request when using getRouteCollection()
Executing an extra command every time a route has been added to the Collection
Creating a controller that uses getRouteCollection() and save the results in the session, cache etc.
Thanks for thinking with me.
Kind regards
I am not exactly sure for what use-case you need this routes but another problem will be that there are routes that you probably dont want to have in your routes list because they are for example routes from the profiler or AJAX routes. So a better approach could be to maintain your own list of routes in a database table where the user can make his choice from.
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 have an application in Cakephp. In my front-end, it only responses for one request and I have used usual CakeRequest() class, and in my back-end, as far as using extjs, I have defined another Request and Response Class for multi-requests and multi-responses. but I have problem in distinguishing between them. I mean where and when one of them is executed. the default cakephp index.php file for front-end is
$Dispatcher->dispatch(new CakeRequest(), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
and for back-end is
$Dispatcher->dispatch(new TestRequestCollection(...
but I don't know the if clause between them.
To what if clause are you referring to?
CakePHP is not designed to use different request classes in the index.php. Not sure what you are doing here. You might want to go the same route I went with Bancha and create a second frontend controller which does different a dispatching.
CI looks for Segment[1] for controller (in controller dir) and Segment[2] for Method. Now, I have specific requirement by business application which needs that I do not want CI to look or by force go to controller dir to load but I will have something like this "domainURL/module_identifier_id/controller/method/".
Here, every request will be coming along with its associated Module's Identifier ID which will have complete module's configuration and other data (controller files, module location where it was uploaded, all menus and their URLs which will have same URL mechanism which we want to design for developers to develop modules and upload) stored in DB.
We need to get this ID and play with it to fetch relevent records and point CI to load controller from where we want it and indeed rest for methods etc every thing needs to be working as it is.
I hope you understand what we are looking for that we have our own main controller type file where all of the requests will be coming with customizing protocol as described above and developers will be following it by all means, that there must be module identifier first and then controller, method etc...
Let me know if you have any query to be cleared on?
I think I would just use routes for this:
$route[(:any)/(:any)/(:any)] = '$2/$3/$1';
This should just rearrange your segments the way you want, without completely changing the way the native routing system works.
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 use php and usually structure my application into model-view-controller so its always accessed via index.php with class and method attributes. Class attribute passed as part of URL specifies controller class and method simply method to be called. This seems to be pretty common, but then I'm always having trouble in figuring out what controllers shall I create. What is the best, easiest and most applicable way to decide on what controllers should be created? I understand it depends on web application itself but must be some general way of thinking to get this process started.
I've found that building controllers based on your application's objects works well, and can take care of most actions you'll want for your app.
Take a look at SO -- there's URLs starting with /questions, /tags, /users, etc. I'd suggest a design which starts by creating a different controller for each object. /questions (or /questions/list) returns a list of all the questions. /questions/[0-9]+ returns the details of a particular question with that id number. /questions/ask returns the Ask Question interface.
As you continue building your app, you might find that the controller-based-on-objects method doesn't meet all your needs. For example, on my site (http://www.wysiap.com), I eventually made a /list controller to simplify my Grails URL mapping. But in most cases I did use this method and it's easy to figure out which controller should be doing different actions.
I recommend to think about the pages you'll need in your applications to accomplish all the requested tasks. You'll group similar tasks on the same page and create as many pages as you need. A page can be sliced in different views for specific actions.
With this in mind you could have one controller per page. Each view of the page can have its own method (action) in the controller. And inside the method of each view you can have a switch() that will enable you to have several tasks for the view. Example:
index.php (Dashboard controller)
/question-list (QuestionList controller, action index, display the whole page)
/question-list/add (QuestionList controller, action add, manage the "add" view with tasks like show-form, validate-form, insert-question)
/profile (Profile controller, action index)
/profile/edit (Profile controller, action edit, manage all the tasks requested for your profile)
...
I design most of my web applications this way and using Zend-Framework