Transcript from the "Oak Routing" Lesson
>> Let's talk about routing. Routing is fundamental to any web application. And Oak has pre built router middleware that allows you to handle different routes, parameters, queries, all of the things that we're doing manually before. And it's basically doing a lot of the string parsing and regular expression and pattern matching in stuff that you otherwise have to do yourself.
[00:00:21] And so let's look at how to use it. So up here at the top, what wanna do is pull in the router from okay, so let's do that. Let's see this a router. You want to enable import IntelliSense for Deno land, Deno land, yes. Just so you can see what that does.
[00:00:58] What it should do, is It doesn't but it will actually go out to the web and give you IntelliSense on modules that you can import remotely. Although support for that seems to be a little sketchy. All right anyway, we pulled in router, so we wanna use that. So let's create a new router instance.
[00:01:21] Which we did and now what we wanna do is handle all these requests with our router. So let's do router.get and then it wants to know what path so this is the route path. So this is our route router, okay. This is our index page we're going to return and then what we get here is the context object again.
[00:01:45] But we don't get the next, right, next is gonna be called for us automatically. So what we're going to do here is just a ctx, but the API is the same, right? So this is we'll just call this index page and then let's do the same thing for, let's make a user's page speed.
[00:02:04] Just like Express we have like /users. Again, let's just return oops, nope, that's not what we want but that is ctx. I need to come here. Let's do. Sorry, I can't use the Escape key. Response body equals users page and then let's do a route with a parameter.
[00:02:37] So we'll do router.get/users/name and then again with our context object and then we can just return, equals. Let's just echo back, the name. How do we get the name, ctx context.params. Again, if you didn't know what can I do with the context, you can just sort of got it and get the IntelliSense and find params that's probably it.
[00:03:16] And then what can we do with params to context.params.what.name, maybe I don't know. Let's try this and see if it works on the task, the task manager popped up, even though I didn't ask for it. Windows is trying to tell me something. All right, so we no longer need to have the app handle the requests.
[00:03:40] So instead, what we wanna do is have the app use the router sorry, app use router. And then specifically, we need to tell it these are the different routes and then we also want to tell it to use this allowed methods. Which allows us to handle all the methods, http methods that we might get, besides just to get okay.
[00:04:13] So now we're handling all these different routes and we're gonna respond differently based on which one we're at. And we're even gonna handle a route perimeter that we jumped through quite a bit of hoops before, but hopes a router makes this quite simple. So let's make sure we're still running here, open an unsupported media type was attempted to be imported as a module.
[00:04:36] I don't think that's right, let's try this again. Look at this, somehow this got pulled in. Let's take this out, we don't want this, there we go. All right, so here's our application running on port 3000 refresh index page. So if we go to users should say Users page and if we pass a name, it should just echo back the name and it does.
[00:05:09] All right, so, that the router from oak makes it quite simple to do complex routing, than your application would likely have. Routing is a fundamental part of any web application. All right, so we implemented that, added the users route. Now, one of the things here, though, that's going to be a problem is that you can imagine if this application was at any size that we would have dozens of routes maybe hundreds of routes, who knows, right?
[00:05:45] And so this app file could be extremely monolithic and so what we don't want to do is just put all of our application code in the app file. Because what if here, we were making some sort of a database call to get users and then here we were doing something else.
[00:06:04] And then we write all of this code to be in the app page, and we don't want that. So really what we wanna do is mimic what Express does and what Express does is it says, okay, well we're gonna put all of our routes in a folder called routes, all right.
[00:06:21] So we need to create files in here and each file will handle a specific route. So for instance, in Express, one file handles all the index routes, doesn't matter if it's a get post, put what have you. Doesn't matter if there's parameters, one file handles all that for users, same thing.
[00:06:38] So we wanNA create that kind of structure. So I'm going to create this file and I'm just going to call it index router.ts. And now what I need to do is I need to be able to reference that router object so that I can add the route here in this file and handle all the code here.
[00:07:01] Now, there's no prescribed way to do this So what I'm gonnado here is just sort of my opinion on how to structure this. But what we can do here is we can export because we have this syntax this like you'll see, keep seeing this use syntax right here.
[00:07:18] So I wanna have a syntax that's similar to this but what we can do here is we can say, export. We could say export default. Export actually just export function use, and then we wanna pass in a path string and we wanna pass in, maybe we want to pass in the router, okay?
[00:07:46] Now in order to actually use the router object, we have to import it and this is where we run into this problem where we're gonna have URL imports all over the place and we don't want that. So now's a really good time for us to create that depths file that we talked about.
[00:07:59] So let's do a new file, call it depth.ts and let's paste this in and then remember, we have to export this stuff back out. So let's export application and router. Okay, and actually here, let's do let's export a default function, And then at the top of this, what I wanna do is import router from the depths file which we can access like this.
[00:08:38] Right now all of our nasty URLs are hidden away out of sight. But we need to import application and application and router from that file as well. Forgot na From our depths.ts, okay. And it's in the same folder here, so we don't need this, just do this. Okay, so here we've got this function and inside of that, what we wanna do is just say this router object which we've passed in needs to be of type router.
[00:09:23] We'll just say router dot oops, I got an uppercase, let me change this, router.get, right. And then we just wanna get the path and then we wanna do something just like we're doing before. We just moving this code in what we're doing before saying ctx.response.body equals index pag, okay.
[00:09:54] Now we need to take out our router here. So let's get rid of this. So we don't need this anymore, instead we're gonna pull in our router file, so import. So we wanted to do routes, there we go, Index router.ts, okay. And then here what we can do is just tell our index router we got a default remember we talked about that I messed it up.
[00:10:31] So he pulled us out, we should be able to get it. Like this, use, there it is and then we're gonna pass in the path, okay? And we're gonna pass in the context, the router object sees me. Okay, so just like that we've moved the logic for our index router into another file and let's just do the same thing for our users routes.
[00:10:57] Let's just do user's router. And then we can just copy over basically everything from the index route into our users router but in this case, what we wanna do is, we wanna have two routes. One is responding to the params but for now we'll just handle the main route and let's just change this to users page, okay.
[00:11:26] And then now we can copy the same line up here, just move this down, just rename it to Users router. Okay, excellent. Let's get rid of this because we're not using router and now it's just, users router.use, users and then we're passing in that router object. Okay, so as just like this, you can see where we're sort of just moving through here and handling paths and moving things into routers and structuring our application, the way an application might be structured.
[00:12:09] Now, I think actually the right way to do this in a perfect world is to actually create a new router in each one of these files. So, in a perfect world, we'd say, const router equals new router like this and then we would say router.get and we would handle all of this stuff here in this file.
[00:12:26] But the problem is as of the time of this writing oak does not handle sub routers like that, it will only take that one router. And so we're sort of stuck to this syntax of kind of mimicking that by wrapping everything in a use function. Okay, are we still running over here?
[00:12:47] File change detected we are. So now do we have something similar? Let's see here. Let's go back Index page. Users page All right, so our router is working very nicely. All right, so we are slowly approximating something that looks like we need it to.