2.2 Route to Controllers
Using a Closure to handle routes is sometimes useful, but usually it's a better option to use controllers to handle requests. You'll learn how to do so in this lesson.
1.Introduction2 lessons, 06:28
2.Create a Sample API2 lessons, 17:23
3.Write the Music Store API3 lessons, 27:11
4.Conclusion1 lesson, 01:04
2.2 Route to Controllers
In the previous lesson you saw how easy it was to define routes in Lumen. You basically just call a method that represents the HTTP method that you want to handle, then the URL for the route, and then finally some code that is going to actually handle that request. And in this case, we used closures, which in many cases would be fine. But I imagine for the majority of our projects, we would want to organize all of our code so that each of our routes are using a method on a controller. Because in doing so it makes our code easier to maintain, it also groups all of the related code where they should be grouped. Like for example we have a group that prefixes all of our posts. So we could say that all of these routes, maybe except for this last one, would be on a post's controller. So we are going to essentially do what we did in the previous lesson, define all of these routes but doing so with controllers. Now inside of the HTTP folder, there is the controllers and this is where our controllers live. Now right now there is just one controller class, it inherits from base controller and this is the controller that we would use as the base class for all of our other controllers. Now there is this example controller and it is exactly what it says this is an example controller. But you can see that it extends controller, there is a constructor if we need to do anything inside of the constructor and of course there's also the methods that we would need to add. Now note the namespace here App\Http\Controllers; whenever we use a controller to handle a route, Lumen has to know where that controller lives. And if you remember whenever we first started talking about the group method, we did so inside of the app PHP file and we saw that the group method was being used and it was grouping with a namespace and then it was setting a namespace here. So this is where Lumen will look for any of the controllers that we use inside of routes PHP because that is what is set here. So that's where we are going to put our controllers. And we're going to start by copying the example control and just changing it to our own posts controller. Now we also need to change the name of the class itself, so let's go ahead and do that before I forget to do that. And then let's start modifying our code inside of our routes. So we're going to start with this first one that retrieves all of our posts. So instead of using a closure here we're going to say that we want to use the PostsController and we're going to use a method on this controller called let's say getAll. So the syntax is PostsController, our controller name followed by an @ sign and then the method name. So let's go ahead and let's implement that on our controller. So we need public function getAll, this is not going to have any parameters and this is simply going to return all posts. So that whenever we go to that same URL, we should see what we saw before and let me just make sure, yes it says all posts. So we'll do the same thing for the second route that retrieves an individual post and we don't have to worry about parameters or anything like that, everything that we learned from the previous lesson is going to carry over into this one. So there's nothing special that we need to do for the postId parameter. So here we're going to use our PostsController again and let's call this method getPost. Now we don't specify anything here with the method name, Lumen is automatically going to take the URL parameter and pass that value to our controller. It's just that the method on our controller needs to have that postID. So, once again, public, function, getPost and then we have our postId and we will simply return post with ID and then that postId. Now for the final route we are retrieving an individual comment on an individual post. So really this would be on a completely separate controller, it would be a comments controller. So let's take our PostsController, let's do CommentsController and we'll also change the name of that class, and we'll also need to modify our method. So, we will first of all get rid of the getALL method because we aren't doing anything there, although, in a real application we would be. And instead, let's just call this getComment, and we have two things, we have the postId and then the commentId. And let's grab the code that we were using inside of our routes file and we will use that here as the return value. So, inside of our route PHP, instead of using this closure, we would instead say, CommentsController, that method was getComment and that's all that we need to do. So we should be able to hop on over to the browser, we can refresh here and something went wrong. Now I know what the problem is but let's go through the process of debugging this. And we're going to start with the console because that is going to tell us what the response is. We can see that the request was for posts and the response was 500, so it's a problem with our code. We don't know what that code is so we need to enable debugging for our application and we do that by going to our environment setup. Now inside of the root of our project there is this .amv.example and we can see that there are several settings here. What we want to do is copy this and we'll paste it and we will rename this to just .env. And then our application is going to use these settings. Now the DB connection we don't need to worry about in this lesson but we will in the next one. But the one that we want is this APP_ DEBUG and it's set to true. This is going to give us a little bit of insight as to what is wrong with our application. So let's go back, let's refresh, and now we see ClassPostsController does not exist. Well, yes it does because we wrote that. But here's the thing, with Lumen, groups do not inherit one another. Inside of app.php, there is this group that's using the namespace of App/Http/Controllers, and then, inside of routes we define another group and this is setting up the prefix for posts but this group does not inherit that's parent group of the namespace. So we need to come in here and we need to also specify the namespace as well. So we'll add another key and then the value is going to be what it was and the other groups. So App\Http\Controllers, and so now if we go back to the browser and refresh, we will see the results that we expected. So we now see all posts, if we specify an individual ID we run into another problem but I can see what that is. This is PostController as opposed to PostsController, so let's change that. We'll go back, refresh, and now we see the post with id of 1. And now let's retrieve the comment with an id of 10, and we see that result. Now, there is an alternative to setting up another namespace here and that is, we could just use the fully qualified name inside of our route. So we could say, that we want to use App\Http\Controllers and then PostsController but for an application that will have a lot of routes, that's not really the best way of going about it. Just add namespace to your group set up and do you will be good to go. In the next lesson we are going to finally incorporate a database and start writing an actual API.