Route And Closure

Think route as an entry point of your application. All the URL filter is done here. You type the URL in your browser's address bar and and route will tell you what to do next. By the name of it, generally, it actually bypass the control to the specific method. Kind of routing the control flow depending on the different URL.

All your Route is defined in route/web.php file. You will define all the route in this file.

Let's start defining some basic route -


            Route::get('myName',function(){
                return "Santanu Bera";
            });
        

Let's say that your domain is app.com, now if you go to the address app.com/myName you will see Santanu Bera in your browser.

Here, get is the HTTP verb or method that defiines the kind of request we are making. In this case it is get as we are requesting through the URL. Now the first argument is the URL part. Whatever comes after the domain name app.com should be in the first argument. In our case as our URL is domain/myName, so the myName should be here in this argument. Note that the backslash here is optional. So, "/myName" and "myName" is same. You can omit the preceding backslash to make the code look more cleaner.

Here also we don't need to provide the full URL. If you noticed we didn't provide the domain name in the first argument. A few more example -


            // app.com/student/numberOfStudent
            Route::get('/student/numberOfStudent',function(){
                return 30;
            }); 
            // app.com/teacher/numberOfTeacher
            Route::get('/teacher/numberOfTeacher',function(){
                return 20;
            });
        

Next, in the second argument, we are using a anonymous function and this is called Closure in PHP. You define list of routes in this web.php file this way and if an URL mathches with the Route's first argument, the corresponding Closure get executed. You can write any statement you want in this Closure. In our above example we are just returning string and integer value. This is very basic and in real life development we never return string or integer, rather we return a View.

A View is an HTML representation what we call Web Page. You can return a View from this function this way -


            Route::get('service',function(){
                return view('servicePage');
            });
        

We will talk about view later.

So the basic part of the Route is it actually filters the URL and decide what to do when a match found. If there's no match found, Laravel throws an error message.

Home Routing

What if we want to return a particular view when someone visits app.com? How do you filter? well, this is how it's done -


            Route::get('/',function(){
                return view('homePage');
            });
        

Route and Controller

In real life programming, we never use Closure, because as we always approach MVC patter, so we should seperate the logic from the Routing file. This is where the Controller comes in mind. If you use Closure for every route in a single file, the code will grow bigger and it will look messy. But with the help of Controller we can seperate the code from the route and we can make the code look more cleaner. This is how it's done -


            Route::get('/getStudents',"Student@getAll");
        

In the above example, in the second argument, we are not using Closure, instead we are using controller. The first part is the name of the controller and the second part is the name of the method that is defined in that controller and these two are separated by @. So when we make a request to app.com/getStudents it will pass the control to the getAll method of Student controller.

Parameter in Route

Have a look at the following routes -


            Route('/getStudent/30',"Student@getStudent30");
            Route('/getStudent/31',"Student@getStudent30");
            Route('/getStudent/32',"Student@getStudent30");
            Route('/getStudent/33',"Student@getStudent30");
            Route('/getStudent/34',"Student@getStudent30");
            ....
        

Now, how far can you go this way? Let's say you have 1000 student. It's kind of pain in the BIG FAT ASS to write 1000 routes for thousand students. And that's where the parameterised routes comes in mind. Now have a look at the following -


            Route('/getStudent/{rollNumber}',"Student@getStudent");
        

Say Thanks to Laravel, it saved you millions of hours with just one line of code. In your URL, whatever comes after getStudent, the above route get matched and the method getStudent in the Student controller get executed. Here, rollNumber acts as an argument that is passed to the getStudent method. So you must define your method that can take this argument. Your getStudent method should look like this -


            public function getStudent($rollNumber){

            }
        

Now you can get student using the url like -


            app.com/getStudent/30
            app.com/getStudent/40
            app.com/getStudent/101
            app.com/getStudent/helloWorld
        

Wait ! Hello World? Yes. everything that comes after the getStudent in your URL, is passed to the method as the argument value. So in your method you must validate if it is really rollNumber or something else.

Optional Parameter

You can have optional parameter in your route. This is done by giving ? after the name of the parameter.


            Route('/getStudent/{rollNumber?}', "Student@getStudent");
        

Wait, we are not done yet! You must give the default value to the parameter in your controller method. So your method should look like the following -


            public function getStudent($rollNumber = 30){
                dd($rollNumber);
            }
        

Now, whatever you pass in the URL after getStudent will be passed to the method as the argument. If you don't provide the parameter in your URL, I mean if your URL is like app.com/getStudent then in the method the argument rollNumber have the default value 30.

Multilevel Parameterised Route

You can have Multilevel Parameterised Route.


            Route::get('/getStudent/{class}/{section}/{rollNumber}', "Student@getStudent");
            Route::get('/getStudent/{class}/{rollNumber}', "Student@getStudent");
        

Now, if you want to have some optional paramenter along with the required parameter, general rule of thumb, your trailing paramter shold be the optional one. It mean the optional paramters should come at the end.

Another imporatant point to note is that, if you have x number of parameter in your route, your corresponding method should take the same number of parameter. And you must provide the default value for all the optional parameter. For example -


            Route::get('posts/{post}/comments/{comment?}', function ($postId, $commentId = null) {
                //
            });
        

Named Route

Let's say you have a route like "/article/comments/reply/date/getDate". And you have to call this route from controller or View. In this situation you must remember the full route path or you have to open web.php file and search for the route then copy the route and switch to the file in which you were working and then paste it. Uff, lots of work. Well, say Thanks to Laravel again that we have a feature for that, we call it 'Named Route'. Now matter how complex your route is you can give it a name, just like a dog has a name. Okay, so here it is how it's done -


            Route::get('article/comments/reply/date/getDate', function () {
                //
            })->name('getReplyDateofArticle');

            Route::get('article/comments/reply/date/getDate', 'ArticleController@getDateofReply')->name('getReplyDateofArticle');
        

Now from the controller you can redirect to a named route like this -


            return redirect()->route('getReplyDateofArticle');            
        

Or, if you are working in View, you might wanna generate the exact URL in your view so that whenever a user click on the link they can successfully get the full path. You can generate the URL like this -


                $url = route('profile');                
        

If the named route defines parameters, you may pass the parameters as the second argument to the route function. The given parameters will automatically be inserted into the URL in their correct positions:


            Route::get('user/{id}/profile', function ($id) {
                //
            })->name('profile');
            $url = route('profile', ['id' => 1]);            
        

Prefix