API Design in Node.js (using Express & Mongo) Exercise 9 Solution
This course has been updated! We now recommend you take the API Design in Node.js, v4 course.
Transcript from the "Exercise 9 Solution" Lesson
>> Speaker 1: Okay so, step nine. You have to implement, there was some missing credit routes in some of these controllers, there were maybe three or four total. All right. So, any questions on that or maybe five, maybe three or four, yeah. Any questions on that? Cuz you guys did it and then we left off, so I didn't really get a chance to talk to you while you were working on it.
[00:00:27] So if you have any questions on it, it's totally the time.
>> Speaker 1: No? Everybody got that? Just super perfect. Okay, so let's see what that looks like then. Let's just check out step nine. I guess if you had any questions you could just check out to the solution branch and then you would just find out right.
[00:00:53] That's probably why people don't have a lot of questions, cuz they just look at the solution. It's like I was going to ask you this but then I looked at the solution. And now I kind of know. That makes sense. So I think this one was missing, right?
[00:01:05] And the category controller, the params.
>> Speaker 1: So remember, this controller method here, even though we haven't defined the routing for it, that's the next step. Based on what we did with the lions and the tigers, we know that there was this method on the router that we can use called param that will look at the ID or whatever parameter.
[00:01:27] What we did with the lions and tigers, we would look through the array of lions and tigers and find one with the right ID and if we did we would attach it to request. It's the same thing we're doing here except we don't have an array we have a database.
[00:01:39] It's the same concept. So, [INAUDIBLE], it's gonna take the ID, and it's gonna see if we can find it in the database first, of this category. If it doesn't find it, I'm just throwing an error here. You can choose to do whatever you want, I'm just saying, there's no category, get out of here.
[00:02:02] But there is, I'm just gonna attach that category to req.category and call it next. And then this function is just error handling on a promise.
>> Speaker 1: Any questions on that? So again that's me grabbing the ID, checking the category collection to find a category document with this given ID.
[00:02:28] If it doesn't find one that means the ID that the client is asking for doesn't exist in the database. Maybe from between the time they got that ID, and sometime now that category was deleted so it doesn't exist. Maybe they went to the blog and they clicked on, they were on the blog page and then they had it on their computer for a week.
[00:02:50] During that week one of the categories got deleted by a admin. So they just went and clicked the button to go get on the categories and then this one didn't come back. So that's one of those edge cases. Or maybe they're trying to hack us and putting in some random ID, I don't know.
[00:03:06] But either way, it doesn't exist in the database. If it does exist, attach it to req.category and call next(), so that's going to allow us, so when we call next() here, because this params is like a middle way before the routes. It's gonna go to the actual request that was called.
[00:03:21] In this case, the only stuff or reason for IDs here is delete a category, update a category and get one category. So it'll go to one of those, depending on whatever the request was. So there, if the request was /api/categories, you know /id delete, then after it's done here, it's gonna go to delete.
[00:03:39] If it was put then others on here would go to put.
>> Speaker 1: So hypothetically speaking, let's say it goes to get one, which means just get just the one category. We already got the category up here, we already did the job. It's done. We already grabbed it. So all we gotta do when we go to get one is just send back req.category.
[00:04:00] It's already there.
>> Speaker 1: Everybody follow me there? How that middleware's working? If it's not quite there yet when we get to the next step with the routes and you connect them together then you'll see, but it's exactly like what we did with the tigers and lions. It's nothing different except we just got rid of the array and ad a database.
[00:04:23] But it's doing the same thing.
>> Speaker 2: I guess so sorry if you're reiterating, but on the promise completion there, the category parameter, is that just returned by the find by id?
>> Speaker 1: Yeah. So I wasn't, I plan on giving promises during this solutions lecture so I'm glad you asked it.
[00:04:45] This is a great introduction to it. So I've been kind of breezing over promises because I've been saving it for this solution, as far as queries. So yeah, who here has experience with promises?
>> Speaker 1: Okay, a lot of people. Cool. So if you do have any expression problems, we're gonna go over it just a little bit.
[00:05:02] We're not, I'm not gonna go into detail about everything a promise is, but just an overall conception of what a promise is. Actually, what we'll do is go through the solution. And then we'll break off. And I'll talk about that. Cause it's a little deep. Yeah?
>> Speaker 2: I think we have some other questions.
[00:05:18] I don't know if you wanna handle these now or-
>> Speaker 1: Yeah, let's do it.
>> Speaker 2: Why do the queries attach to exports?
>> Speaker 1: Because we are going to use them in our router on the next step. So, they're being exported because just like lions and tigers, so you would have something like this app.get and some router file like slash let's say lions and then you have this function here,
>> Speaker 1: Request, res, next. This is what we had before, this is exactly what we had. What we're doing now is, we're not going to place this function in here anymore. We're actually just gonna put in one of these methods that were exported. So that's what we're doing. We're just defining those functions in another file.
[00:06:07] These are the controller functions, we're just getting rid of them and we're defining them here in this other file. So we need to export them so we can import them on the next step. Or require them on the next step.
>> Speaker 2: Okay, and I think there's kind of a trail going on here in the chat room, but why don't you use exec instead of then.
[00:06:28] Exec returns promise by default and is good practice with Mongoose.
>> Speaker 1: Yeah. So if you do, if you come down here and you say .exec, and it's the same thing. Why did I use it? Save keystrokes, it's the only reason. But yeah, if we do exec and then you say .then, yeah, it's totally a promise.
[00:06:49] If you don't wanna use promises, exec takes a node.callback as well. I don't even use exec and I don't even use the built-in promises in [INAUDIBLE] either. I usually use Blue Bird and I promisify the entire Mongoose library, which is a little advanced. So I just don't use exec.
[00:07:06] Because the promise library that Mongoose uses is actually not that good. It doesn't really follow the A+ Promise specification that we'll get into in a little a bit. So I don't really like it. So I wrap it in something else.
>> Speaker 2: And I think he's following up on that.
[00:07:23] Why aren't you creating a class and then export a class?
>> Speaker 1: Why are we?
>> Speaker 2: Instead of exporting multiple times using export.
>> Speaker 1: It's just one way of doing the same things, so if you want to get classical and make a class, you could totally do that. Sometimes I like to get functional so I don't really like to do.
[00:07:45] There's nothing wrong with that. The reason I did is because this is the style that I chose to do. You could have alternatively just said, module.exports and put all the methods on here, so paramas and the what else do we have, git, you could have done this too.
[00:08:06] It's up to you. So, maybe you don't really feel like writing key value pairs, you just want to write variables instead. So, it's a stylistic thing. No big reason, it's just sometimes I do this way, sometimes I module.exports.
>> Speaker 1: Anything else? Is that it?
>> Speaker 2: Yeah, they're asking about happy.js has validation for routes.
[00:08:28] Should we be doing any input validations? Like using express validator?
>> Speaker 1: Yeah, happy.js is pretty awesome. So yes. Well, there's like different layers of validation. So first, you should validating on client first of all, have whatever form submitting from a client that should do validation first. And then, what you should do is when you get to express, if you want to add an extra layer in between the client validating and then the database validating and that's like through a middleware.
[00:08:58] You can also do that too, there's nothing wrong with that. And we'll get into Mongoose and how it uses middleware too. And how we can talk about that, so we'll get into that. But yeah, there's nothing stopping you from making like a middleware function that does validation. But that's probably not the best place to do it, because middleware is more tied to routes .Whereas I see validation more tied to models.
[00:09:17] So, I would probably bake that validation into the models itself and using the middleware that's provided by Mongoose, which we haven't learned yet, which we will today, though.
>> Speaker 1: Okay. Sweet. So any other questions on this? Again, it's the same thing we did before except we are not modifying it already.
[00:09:39] We are creating a database, it's the same concept. Go find it, yes
>> Speaker 2: I got a question.
>> Speaker 1: Yes?
>> Speaker 2: So I understand line 18 exports .GIF, is kind of like a handoff to the GIF that's coming in from the request? That line four, exports.params, what does that actually hook up?
>> Speaker 1: So these names are arbitrary. I just name like this because there just happens to be, so what you're saying is like, yeah, there's a verb call get so that's where that lines up. Where does params come up? Well, I don't know what step it's on, but when we were doing lines, we had a at.param.
>> Speaker 2: That's what I'm asking.
>> Speaker 1: This is where this hooks up at.
>> Speaker 2: Do you have it hooked up here? I remember it from lines, I don't see it here.
>> Speaker 1: The routing is the next step after this. It's step 10, this is step 9. If you look at step 10 you'll see it.
[00:10:31] You're about to do it after this. So you'll see, we will use this. We haven't hooked the routing up at all. We are just defining the crutch for it. I just naming it purpley because I know for sure we will have the parameters out because we have ID's down here.
[00:10:46] So I know that we are going to have this so I made it. That is why I can't figure out where it is hooked up to. It is an orphan.
>> Speaker 2: Yeah.