Routes, arguments, views and HTTP methods in Laravel
Content Index
- Available HTTP route types and methods
- Named routes
- Dynamic routes and parameters
- Importance of Modularizing Routes in Laravel
- Problem with Disorganized Routes
- Solution: Group and Reuse Controllers
- Tip 1: Reuse the Same Controller for ID and Slug
- Tip 2: Leverage Parameters and Authentication
- Benefits of Modularizing
- Benefits of Modularization
- Common Errors and How to Fix Them
- Frequently Asked Questions (FAQs)
- Conclusion
As we presented earlier regarding the file and folder structure in Laravel, paths are part of these paths.
Routes in Laravel are the entry point for any application.
In my experience, understanding them well is the first step to mastering the framework.
Routes in Laravel are a flexible scheme that links a URI to a functional process, which can be a function, a controller, or even a Livewire component. Simply put: when a user types an address into the browser, Laravel looks for a match in the routes files and executes the corresponding action.
The main file that manages this process is routes/web.php. Here, we define the routes that respond to browser requests, while api.php, console.php, or channels.php are used for other contexts such as APIs or console commands.
When Laravel receives a request, it passes through its Front Controller (usually public/index.php), interprets the URI, and associates it with the corresponding route.
Routes are a flexible scheme that we have to link a URI to a functional process; and this functional process can be:
- A callback, which is a local function defined on the same routes.
- A controller, which is a separate class.
- A component, which is like a controller, but more flexible.
If we check in the routes folder; we will see that there are 4 files:
- api: To define routes of our Apis Rest.
- channels: For fullduplex communication with channels.
- console: To create commands with artisan.
- web: The routes for the web application.
Available HTTP route types and methods
The one we are interested in in this chapter is the web.php; which allows us to define the routes of our web application (those that our client consumes from the browser).
The routes in Laravel are a central element that allow link controllers, and to be able to programmer our own processes; that is, the routes do not need the controllers to be able to present a content; and therefore, it is the first approach that we are going to present.
If you notice, we have a route already defined:
Route::get('/', function () {
return view('welcome');
});Which, as you can imagine, is what we see on the screen just when we start the application.
Note that a class called Route is used, which is imported from:
use Illuminate\Support\Facades\Route;
Which is internal to Laravel and are known as Facades.
The Facades are nothing more than classes that allow us to access the framework’s own services through static classes.
Finally, with this class, we use a method called get(); for routes we have different methods, as many methods as type of requests we have:
- POST create a resource with the post() method.
- GET read a resource or collection with the get() method.
- PUT update a resource with the put() method.
- PATCH update a resource with the patch() method.
- DELETE delete a resource with the delete() method.
In this case, we use a route of type get(), which leads to using a request of type GET.
The get() method, like the rest of the methods noted above, takes two parameters:
Route::<ResourceFunction>(URI, callback)- Application URI.
- The callback is the controller function, which in this case is a function, but it can be the reference to the function of a controller or a component.
And where "ResourceFunction" is the get(), post(), put(), patch() o delete() method.
In the example above, the ”/” indicates that you are the root of the application, which is:
http://larafirststeps.test/
Or localhost if you use MacOS or Linux using Docker.
In this case, the functional part is an anonymous function; this function can do anything, return a JSON, an HTML, a document, send an email and much more.
In this example, it returns a view; to return views, the helper function called view() is used, which references the views that exist in the folder:
resources/views/<View and Foldes>By default, there is only a single file; the one called welcome.blade.php, and yes, it’s the one we’re revering in the path above with:
return view('welcome');Note that it is not necessary to indicate the path, nor the blade or php extension.
Blade refers to Laravel’s template engine which we’ll talk about a bit later.
If you check the view of welcome.blade.php:
You’ll see all the HTML of it:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
***So, if we create a few more routes:
Route::get('/writeme', function () {
return "Contact";
});
Route::get('/contact', function () {
return "Enjoy my web";
});And we go to each of these pages, respectively:
And
Route::get('/custom', function () {
$msj2 = "Msj from server *-*";
$data = ['msj2' => $msj2, "age" => 15];
return view('custom', $data);
});views/cursom.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>{{ $msj2 }}</p>
<p>{{ $age }}</p>
</body>
</html>Named routes
Another configuration that cannot be missing in your application is the use of named routes; as its name indicates, it allows you to define a name for a route.
*
Route::get('/contact', function () {
return "Enjoy my web";
})->name('welcome');For that, a function called name() is used, to which the name is indicated; to use it in the view:
<a href="{{ name('welcome') }}">Welcome</a>This is particularly useful, since you can change the URI of the route, group it or apply any other configuration to it, but as long as you have the name defined in the route and use this name to reference it, Laravel will update it automatically.
Dynamic routes and parameters
Routes can also receive dynamic parameters:
Route::get('/user/{id}', function ($id) {
return "Usuario con ID: $id";
});You can make them optional:
Route::get('/user/{name?}', function ($name = 'Invitado') {
return "Hola, $name";
});And, of course, pass data to a view:
Route::get('/custom', function () {
$msj2 = "Mensaje desde el servidor";
$data = ['msj2' => $msj2, 'age' => 15];
return view('custom', $data);
});In this example, the custom.blade.php view receives variables and displays them using Blade.
I love this approach because it simplifies communication between the server and the interface.
Importance of Modularizing Routes in Laravel
I want to tell you about something I consider very important: modularizing your routes and controllers. By controllers, I mean the functions or methods that process requests. To illustrate this, I'm going to show you my previous version of Laravel development so you can see the comparison.
In the previous version, I had a bunch of GET routes like these:
Route::get('{tutorial:url_clean}', [\App\Http\Controllers\Api\TutorialController::class, 'show']);
Route::get('/coupon/check/{coupon}', [\App\Http\Controllers\Api\CouponController::class, 'active']);
Route::get('update-progress-by-user', [App\Http\Controllers\Api\TutorialController::class, 'update_progress_by_user']);
Route::get('/get-detail/{tutorial:url_clean}', [App\Http\Controllers\Api\TutorialController::class, 'getAllDetail']);
Route::get('/by-slug/{tutorial:url_clean}', [App\Http\Controllers\Api\TutorialController::class, 'by_slug']);
Route::get('/class/free/by-slug/{tutorial:url_clean}', [App\Http\Controllers\Api\TutorialController::class, 'class_free_by_slug']);
Route::get('{id}/class/resume', [App\Http\Controllers\Api\TutorialController::class, 'get_class']);
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::post('inscribe/{tutorial:url_clean}', [App\Http\Controllers\Api\TutorialController::class, 'inscribe']);
Route::get('user/my-courses', [App\Http\Controllers\Api\TutorialController::class, 'my_courses']);
});Problem with Disorganized Routes
The reason for so many routes is the nesting of courses, sections, and classes, similar to how Udemy works:
- Main course (tutorial).
- Course sections.
- Classes within each section.
Additionally, depending on the user:
- If they bought the course, the tutorial has more information.
- If they haven't bought it, we only show a basic detail.
This led to creating many separate routes to handle different views (detail, full, simple) and different filters (ID or slug).
The problem is that these routes become hard to understand, with long and repetitive names, and modularity is lost.
Solution: Group and Reuse Controllers
To simplify, we group the routes and leverage the same controllers:
Route::group(['prefix' => 'tutorial'], function () {
Route::get('', [App\Http\Controllers\Api\TutorialController::class, 'getAll']); // general list
Route::get('simple/get-by-slug/{tutorial:url_clean}', [\App\Http\Controllers\Api\TutorialController::class, 'getSimple']);
Route::get('simple/get-by-id/{tutorial}', [\App\Http\Controllers\Api\TutorialController::class, 'getSimple']);
Route::get('full/get-by-slug/{tutorial:url_clean}', [\App\Http\Controllers\Api\TutorialController::class, 'getFull']);
Route::get('full/get-by-id/{tutorial}', [\App\Http\Controllers\Api\TutorialController::class, 'getFull']);
});Tip 1: Reuse the Same Controller for ID and Slug
If you want to fetch a tutorial by ID or by slug, you can use the same controller. You just need to define additional routes:
Route::get('full/get-by-slug/{tutorial:url_clean}', [Controller::class, 'getFull']);
Route::get('full/get-by-id/{tutorial}', [Controller::class, 'getFull']);This reduces routes by half and makes the code cleaner and more maintainable.
Tip 2: Leverage Parameters and Authentication
Instead of creating additional routes, you can leverage parameters and authentication to return more or less information:
public function getFull(Tutorial $tutorial)
{
$user = auth()->user() ?? auth('sanctum')->user();
if ($user) { // Authenticated user: show all tutorial information
} else {
// Unauthenticated user: show only basic information }
}For users who haven't bought the course, only basic information is shown.
For users who bought the course, all information (full) is returned, including sections and classes.
An extra parameter can be passed via request to calculate additional prices, but it is not recommended to pass sensitive information directly, as it could be hacked.
Benefits of Modularizing
Easier to maintain: You don't need to modify multiple routes or controllers to add a new parameter.
More readable: Routes are grouped and have clear names.
Controller reuse: You can use the same method for multiple routes and parameters.
Security: By using auth or sanctum, sensitive data is handled correctly.
Benefits of Modularization
Easier to maintain: You don't need to modify multiple routes or controllers to add a new parameter.
More readable: Routes are grouped and have clear names.
Controller reuse: You can use the same method for multiple routes and parameters.
Security: By using auth or sanctum, sensitive data is handled correctly.
Common Errors and How to Fix Them
Problem Cause Solution
Route not found Incorrectly spelled URI or duplicate route Check with `php artisan route:list`
Error 419 or CSRF Missing token in POST forms Add `@csrf` to the forms
Outdated route cache Changes made without clearing the cache Run `php artisan route:clear`
Frequently Asked Questions (FAQs)
Where are routes defined in Laravel? In the files within the `routes/` folder, primarily in `web.php`.
How do I pass variables to a view from a route? Use the `view()` helper and pass an associative array with the data.
What is the difference between web routes and API routes? Web routes load sessions, cookies, and views; APIs are lightweight and stateless.
How do I list all available routes? With `php artisan route:list`.
What's the best way to group routes? Use `prefix()`, `middleware()`, or even `Route::resource()` for REST controllers.
Conclusion
Modularizing your routes and controllers is fundamental to keeping a project organized, scalable, and secure. This avoids the chaos of long and confusing routes and allows you to leverage parameters and authentication to handle different scenarios with less code.
Mastering its use not only makes you more efficient, but also gives you total control over the structure and performance of your application.
The next task is to learn how to use Laravel's powerful command line, Artisan.
I agree to receive announcements of interest about this Blog.
We will take the first steps with the routes and the views, to start seeing screens through the browser; we’ll also cover using controllers with views; redirects, directives and blade as template engine.