As your application grows, it's easy to end up with a long list of route handlers and helper functions. In this lesson we'll look at strategies for keeping things organized and manageable.
Now that we've seen various routing capabilities, I want to show a couple of code organization tactics that you can use. First of all, let's go ahead and get rid of these errors that are in here, it's annoying.
You can see that we have several routes that are just handling this /username, and we've got to redefine that path in all of our route handlers. And so, one way to do that, when you've got several handlers, is to use the App.Route method.
You give it the path one time in App.Route, and then, you can chain all of your handlers off of that. We can just say App.Route username, and then define our All, our Get, our Put, everything. Make sure our App is still working, and yes, it is.
Now, the next organizational technique is a little more involved, and so, we're going to do a little bit of prep work for this. We are going to go ahead and move these utility functions or helper functions that we have created into their own file, called "HelpersJS."
I've already set up the shell of this file, so that we are exposing all of those functions from that. And so, we'll now go and update all of these references in this file, so that we can still access these functions.
Now that we have that updated, what we're actually going to do, we are actually going to grab all of these handlers, and we are going to move them over to their own file in usernameJS. Then, we are going to re-import Express, and we are going to call it Express.Router to create our own router instance.
By default, Express gives you a router and that's what we're using when we call "App.Get," "App.Put," those things, but in this case, we are going to create are own instance of a router. You'll see a lot of times in documentation and things, it's referred to as a mini-app, because it really is it's own self contained instance.
And so, once we get everything updated in this file, we've got access to our helper functions and the FS module, and you can see we're now just updating these routes to be on the router. You'll notice that the path is just a/, and that's just because when we define this, how our app uses this, we're going to define the path there.
We're actually going to say App.Username, and then, we will import our router and say, "When you find this user name path, I want you to use the router we are importing here."
But if you go back to the app and use it, you will see that we are getting in every here, and the error isn't extraordinarily helpful or descriptive.
But what's actually going on is that when you create a router like this, it's actually completely separated. And so, it doesn't actually get the URL parameters that we normally do, unless we pass in this options object and set and merge params to true.
Once we do that, we can go back and see that our app is, in fact, working. This allows us to do everything that allows us to move username handling into its own file. In our case, since we're not really doing different paths and things, it's probably not terribly useful, but if you have sub-paths in a section of your app, it can be really useful.
If we defined a Get handler here for /edit, and we'll just send back some text. But then, if you go into our template and redefine this link, the edit link, so that rather than editing it in place, it's going to go to /edit, we can then send back a response there.
And so, you can see how defining those subpaths gets a lot easier and more maintainable if you break things out into their router file.