This course has been updated! We now recommend you take the API Design in Node.js, v4 course.
Transcript from the "Exercise 6 Solution" Lesson
>> Speaker 1: So the solution for this is, for mine at least, was let's look at config.js. So there's my solution to config.js. We've done a lot of error checking and stuff here, just to make sure that the merge actually happens correctly. So what you could have done is really just required the file, which would give you an object and just put it there.
[00:00:22] That would be great. But there's a lot of edge cases, so I'm checking for those edge cases. I think I'm still missing one, now that I'm looking at it. So what I'm doing here is I'm doing a try catch. Anybody not know what a try catch is?
[00:01:05] And I can do whatever I want here. It won't stop the server from executing because I caught it with the try catch. See what I mean? We could check that out here. Let's do it in Chrome. We'll go into Chrome and, this is really painful to write in, but if I was like try and then throw new error
>> Speaker 1: Oops, right then I say error, or I'm sorry catch, and I grab the error here.
[00:01:59] So I do that, it still executed 1 + 1 even though I threw an error. That's because I caught the error myself. Right, whereas before if I were to say throw new error and then try and do 1 + 1 underneath it, it wouldn't run, right? So if I had a function that says var, this will say error or err.
[00:02:19] It's a function. And the first thing it does is throws a new error.
>> Speaker 1: Right, and then right underneath it, it tries to do 1 + 1.
>> Speaker 2: They're talking in chat that if this is configure related, wouldn't you want the server just to stop?
>> Speaker 1: If it's configure related, would you want the server to stop?
[00:02:47] Probably, maybe. Probably want the server to stop. But, yeah I guess it depends on how sensitive the things are in your config. And they probably are very sensitive, so probably. The other alternative is to put all of the sensitive stuff on the main config object, so that way the server can still run, even though it couldn't require the appropriate file.
[00:03:12] But then, of course, you still have hiccups in the different environments. But this was specifically for development. So, this isn't keeping production and testing in mind to help ease development.
>> Speaker 1: But you could also be on the other side. It's, well I wanna enforce that you always do this.
[00:03:31] So it's kinda however you wanna do it, so.
>> Speaker 1: Yeah but everybody get me? So now I threw this error, I didn't catch it. And then I tried to say now do 1 + 1. It's like no, I caught it, there's an error here. But the try catch above will allow me to continue to go.
[00:03:52] So that's try catch.
>> Speaker 1: So it's like try this code, if there's an error, catch it here. So, what I'm doing is, the thing I'm worried it might error out, is this require statement, because there's a lot of stuff going on here, this could be wrong, I don't know, hopefully it's not because I'm using these actual names here, but it could be something wrong and there might not be a file.
[00:04:17] If config.env ended up being Snickers, there's no snickers.JS. And then this would error out. If you tried to require something in node and that file doesn't exist, it would throw and error. So that why I'm trying to catch this error. And then down here, I'm like so even if it did find that file I want to make sure that that file actually exported something and not.
[00:04:37] I want to make sure that it didn't export the number negative one, or the number zero which is a false evalue. So, it's either going to be whatever it is, or it's gonna be an object. I can even test it like I want to make sure that it actually is an object, right?
[00:04:51] So, you get even crazier with it, but it's just testing that. And then, if it does throw an error, just default to an object so that way the merge still works, because merge needs an object. So that's why I did this try catch. Probably don't need it but just catches some edge cases.
[00:05:08] And then down here I'm just merging them too. So grab this object, stick it on here. So the one that we would grab, because default is gonna be config.dev, which is development, that's gonna be the development.js. Only thing in here is logging is true. Definitely want logging in development, so I turned that on.
>> Speaker 1: So that's for the config. And then as far as the API.
>> Speaker 1: All I'm doing is just requiring those routes, those routers inline. What you probably might have done is like you would require them up here, save them in the variables and pass them down. You could do that.
[00:05:44] But I'm not going to use that many routers, I'm just gonna require them in line. Save some key strokes. So, if you got all this working then what you should be able to do is now, my server's on, I should be able to interact with it. So if I type in http I'm using http pi here, if you wanna use post man or whatever or curl whatever your flavor is localhost 3000 and then I left a note in one of these files about like the actual routes.
[00:06:16] Where did I leave that note?
>> Speaker 2: API users.
>> Speaker 1: API users, I left the note Well, maybe I didn't. I left a note about how to figure out where the routes are, maybe it's not in here, so somebody tell me what would be the URL if I wanted to do a GET request to categories?
[00:06:41] What's the URL? Because if I go to category routes, it's just like slash. So that means if I go to slash, so if I do a get request of this, I should get categories, or even that, right?
>> Speaker 2: No.
>> Speaker 1: Nope, cannot get, 404. So that's definitely not the URL, but that's what it says right here.
[00:06:59] So what's the actual URL for this, Dave?
>> Speaker 2: Some user ID.
>> Speaker 1: Right so we gotta take a step back. We gotta go to see what's using this router? So let's go a step, let's walk backwards. So we'll start here. So this is route, remember? Remember I told you don't think of this as slash, think of this as route.
[00:07:15] This is the route, so this is whatever the route is. So we gotta go figure out whatever the prefix is or the parent is. So we'll back up one and that's api.js, and if it's categories, it's slash categories. Okay, so you're slash categories, got it. But wait, you're being exported too.
[00:07:30] So you got to go figure out what's using you so we'll back out of this right and we'll go to server dot js and we'll see, slash API, right. So the real URL for category would be\api\categories. That's it. So \api\categories. Mark.
>> Speaker 3: I don't know if you want to handle this now or not but on line ten of server.js it says, to set up global error handling.
[00:08:03] Can you give an example of how you'd do this?
>> Speaker 1: Yeah, I guess I forgot that.
>> Speaker 3: Also they were asking can you use dot slash here?
>> Speaker 1: Dot slash, no dot slash is for file paths which are different than URL routes, so I wouldn't use dot slash.
[00:08:16] We're not trying to access a file, we're trying to access a URL. But yeah, global error handling, I think I forgot that one. So the way I would do that, so, when I say global I mean for the entire application. You have to do that in the middle or stack, so I would just do it down here.
[00:08:28] So, I'll just say app.use. All right, you should probably write this in another file, actually that's what I'm gonna do. So, I would go to middleware.js. I make a new one in here, I'll call it error, or err.js. And it'll just be a function, module.exports equals our error, our response or our request.
[00:08:53] Our response, oops, and then next.
>> Speaker 1: And then what I would do is just, for now, to say console.log or .message. And then I would send up, send back a response back res.send
>> Speaker 1: Or res.status. Just probably don't wanna do this, I'm just gonna do this for now.
[00:09:25] Just a generic 500 server error and then ab.use, I'll import that in here.
>> Speaker 1: Which is in the middleware/err.
>> Speaker 2: There's a question on what's better requiring on top and passing in the variable name, or on the router?
>> Speaker 1: There's no better or worse. It works the same either way.
[00:09:51] The thing I think about, if I'm going to use the variable in more than one place, then I'll require it. If I'm only gonna use it once, sometimes I'll do it. Like for instance, I'm only using err once, so I made a variable for it, but I could have just required it here.
[00:10:06] It's whatever is more readable for you. It might be better to just require everything up top so it's all uniform. But the requires are not asynchronous so it's fine. It's not like [INAUDIBLE] 2015 where you absolutely have to import everything up top.
>> Speaker 1: So yeah. Actually I'm gonna switch that around to use a different router where it's like this instead.
>> Speaker 1: There we go. So then in here I could just do err. So that's how we set up a global middleware. So you'll put this here you could put this in api.js wherever. But that's how I would do it. But where was I? Yeah, so that's the URL for category, so if you follow me again on server.js, so if I go to /api, go to this router.
[00:11:10] Okay, I'll go to that router. And then if I go to /api/categories, okay, I'll go to that router categories. And the on the root, for a git request, so if i just do /API/Catsit, qwerty. Oops, well i guess i just start the server. Wait did it freak out?
>> Speaker 1: Server.js.
>> Speaker 1: I forgot the e in middleware, there we go. NPM start, cool so that's running. Now if I go to api/categories, there we go, "ok" : true. That's categories, right? And just to show you that that's categories. If we go and change this to ok meow meow.
>> Speaker 1: Meow.
>> Speaker 1: Meow. Let's try this. And it's the same thing for all the other resources so, users same thing, posts same thing, anything else. Everybody follow that?
>> Speaker 1: Any questions? I mean, as far as triggering the error middleware? So let's see how that works? If I come in here and I say next.
>> Speaker 1: I was gonna put a return here, just to make sure it doesn't try to do anything. Return next.
>> Speaker 1: New Error.
>> Speaker 1: All right, so if I do that, that should go down to the stack, all the way to this. Let me make sure I made that right, yeah.
[00:13:32] That should go all the way down there and do that, so let's check it out. What was that request for?
>> Speaker 1: It was this. Categories. Okay, so let's try categories.
>> Speaker 1: Hm. There it is, yeah, so, yeah.
>> Speaker 1: It's working. That's err.message right there. [COUGH] All right, so if I go back to server.js or err.js, that's err.message, right we we're like, 'THIS is the error, let's try that again, so you can see, I'll clear the console, request, THIS is the error, so it's totally working.
>> Speaker 1: I just did error.message, that's why it looks funky. Just put error, you'll actually see the real error.
>> Speaker 1: There it is, messed up, or if you wanna see like, the real, real error, then you put err.stack. Then you do that, then you get a stack choice.
>> Speaker 1: Cool, all right, any questions on this stuff?
>> Speaker 1: I thought this stuff was kinda cool. I thought how everything just came together as far as like just plug this router up and guaranteed to have this get request or like how the config can turn stuff on and off depending on the environment and load up different files.
[00:15:09] I think that's pretty cool.