API Design in Node.js, v3 API Design in Node.js, v3

Wiring Up CRUD Controllers Solution

Check out a free preview of the full API Design in Node.js, v3 course:
The "Wiring Up CRUD Controllers Solution" Lesson is part of the full, API Design in Node.js, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Scott live codes the solution to the test where it checks for CRUD controllers.

Get Unlimited Access Now

Transcript from the "Wiring Up CRUD Controllers Solution" Lesson

>> Scott Moss: So those are those tests. And now we actually gotta hook the controller up to the controllers, the item's controller, which is all these other tests are failing because of it. So if we go over to item controllers, we see it's just exporting a default object here, which is breaking, like, our route, and breaking all this other stuff.

[00:00:17] Well to get this to work, we can just look at what list control is doing then. It's importing that crudControllers function at the bottom here that you didn't have to touch. Because these are actually creating the crud controllers. Given a model, it returns an object that references those functions that we created above, and passes in the models.

[00:00:36] So that's how we get the models there. Cuz we're passing it in when we create our crud controllers. So I just gotta use this as an export. So list controller's pretty much already doing it. You can see the import.crudControllers function. It imports the list model. And then by default it just exports the crud controllers and passes in the list.

[00:00:51] Which again, exports that object right there. With removeOne, updateOne, getMany, getOne, which is exactly ready to be used for routes. So we're gonna do the same thing. In fact, we can just copy it and go over to Item Controllers, paste it, and then change List to Item.
>> Scott Moss: And that's it.

>> Speaker 2: Crud should now work for any of those three types of models, right?
>> Scott Moss: There you go, that's right. They're generic controllers, and they work for anything. You just pass in the models, it'll work. And that's why we made them that way. We could have just made each one for every single model ourselves, but they all would've end up being the same thing.

[00:01:33] The other beauty of this is that, like, for instance, like I said, REST is very blurred. So now if you've got to deviate from the path, for like, whoa, normally we do a generic REST, getOne for item. But for this scenario we wanna do something a little different for getOne.

[00:01:49] You can overwrite it, right? So you can just come in here and say, all right, yeah, we've got credControllers, cool. I'll just go ahead and spread those. But I wanna overwrite what getOne is, but getOne is now gonna do this. And now you can overwrite it to be something completely different.

[00:02:04] So this allows you to do that. So you can opt, you get all the defaults REST controllers. But if you've gotta overwrite them to do something specifically for this model, you can do it like this.
>> Speaker 2: Like you wouldn't want a user to be able to delete themselves?

>> Scott Moss: Like if you don't want a user to delete themselves, exactly. Anything that's like outside of the range of what REST does. Then yeah, you would have to overwrite it with something like this. Yep, that's a good example.
>> Scott Moss: All right, so now if we run some tests here,

>> Scott Moss: Cool, now all the tests pass.
>> Scott Moss: Good to go, okay.
>> Speaker 2: In your solutions you've got Try-Catches around everything, is that-
>> Scott Moss: Yeah, that's just a more. Well, I mean we're gonna get into error handling next. But yeah, that's just better error handling. Yeah, you wanna put Try-Catches around stuff to make sure things don't break in a server environment.

[00:03:09] Cuz if your server breaks from an error being thrown, then your server's gonna break, it's gonna stop. All right, if you don't have some process manager managing your server, then it won't even restart. So you have to restart it manually. So try catch prevents that from happening. So that's just a more battle-tested way of writing code.

[00:03:26] But the test wasn't looking for it, so I didn't do it the demonstration.
>> Speaker 2: And can that be moved into, so that's in each of the methods. Can it be moved somewhere else so that you have.
>> Scott Moss: Yes, you can, you can move it. You can wrap all your controllers and then Try-Catch on the route level.

[00:03:44] That way you don't have to do it on every single one yourself. You can bump Try-Catch all the way up as far as you want. You can even just listen for unhandled, cuz when something throws an asynchronous task and node, it's not on the main loop, it's somewhere else, right?

[00:04:00] So it catches it eventually. So node has a way for you to listen for unhandled promise rejections. So you can listen to say, hey, when any promise rejection is thrown, which is an async/await, let me listen for it and handle it here. So you can also do that, which is not the best way.

[00:04:14] But yeah, you could push Try-Catch up as far as you want, all the way up to where whatever's calling it. So if I had a function that was async, and I had another function calling it another function, calling it another function, calling that, I could do Try-Catch all the way up here if I want, versus doing it here.

>> Speaker 2: Is it important in these methods just because you're using awaits?
>> Scott Moss: Yeah, when you use await you have to use Try-Catch to handle errors, because it's treating it as it's synchronous. If you're using a promise then you would do a .catch versus a Try-Catch. So yeah, you would have to do a Try-Catch specifically because you used await.

[00:04:44] So that's the, I guess that's the cons of using async/await is that you now have to use a Try-Catch. But there's ways around that too.