Hello! Hopefully you found this tutorial useful. All the code in the video is available on GitHub here - github.com/JasonMerrett/nodejs-api-from-scratch. Let me know if there's any specific topics you'd like me to cover in future videos of this series 😄
It would be cool to see the blog finnished with a react front end and add an eCommerce section to it as well! I've been trying to find a good way to build m own website and I love how you involved typescript with express using classes!! And i'm currently building my site with this tutorial!!! Thank you!!!!
Hi brother! Your style and the way you follow while building this app is really beneficial and informative. I hope you can post more videos just like that. Wish you the best
It was a great and useful tutorial. Please don't stop. Continue this kind of video, like a master child or more complex content! thank you for sharing with us such a nice tutorial.
Thank you for this video, it's well presented and exactly what I was looking for. Tip for any other newbies whose HTTP request hangs indefinitely - turns out I missed calling the next() callback in my validation middleware, so the service code never executed (and hence never moved onto anything that triggered a res() response to reply to the HTTP client).
Thank you! Truth be told I've never used Turborepo but I've just had a quick look and it looks really good. I'm sure I can fit it into a future video :)
Hi Jason, your video is greatly helping me to get into web development, please keep it coming! I would be really happy if you could spare the time to answer two of my questions that came up while watching this video: 1. Can you explain why you are using async/await AND Promise in your controller file when it comes to handling the create method for instance. Is it best practice to define a return value here? And why exactly ""? Could I also use the Post interface as a response type here instead of ""? 2. This seems to be a really advanced approach, I wonder where I can find more information on MERN stack with OOP. Do you have any sources such as documentation or books that you could recommend?
Hi, glad to hear my videos are helping and good luck with your web development journey! 1. The reason why Promise is used is to indicate that this function is asynchronous and will run in the background unless you use something that will stop that. So if you called this.create() the rest of your code would continue to execute but you could also call it like await this.create() or this.create().then(). Essentially, even though it doesn't explicitly return a promise like you would see if you did "return new Promise()" it still technically returns a promise when using async/await. Having Promise as the return type acts as a sort of warning too as if we tried using the function synchronously it might not works as the developer expects! We use the Response interface because that's what we are returning "res.json({})" or void because we could also call next() which doesn't return anything. We don't actually return a Post object but instead include it as part of the JSON that gets returned from the res object. 2. I don't have anything specific to recommend as most of the books I have are quite specific and if you are just getting into web development I don't think they would be helpful just yet. There are lots of videos on RUclips from channels like TraveryMedia, JavaScript Mastery, Lama Dev to name a few. Hopefully this helped!
It is a well structured, detailed video about Typescript. It helps me a lot. Brother kindly, if you enlighten about the product list, update and delete the product with image upload (normal or S3) , it will be very beneficial. Waiting for your valuable response.
Thank you for the tutorial, can't wait for the next episode. I'm a php dev and trying for the first time node as backend. It look very interesting. Can we use mysql or postgresql with node(express)? Thank again again
Hi, I'm glad this series is helping! Yes you can use MySQL or PostgreSQL but you'll need to use an ORM library that supports them, TypeORM seems to be a popular choice. You should be able to do most things the same in regards to the code from this video but replace mongoose with TypeORM and use TypeORM for creating models. TypeORM has good documentation which should give you a good idea of how to replace mongoose. Hopefully this helped :)
Thank you so much for that, It was really helpful. There is just one thing that I would recommend. I think you could explain a few more steps. Because sometimes you are just typing and typing and typing.......... If this is the case, you could do just like 30 minutes and share the git code. But please do not get me wrong, your video was very useful I really enjoyed that.
Thank you, I've noted your suggestion. Going forward I'll aim to do videos that are a bit quicker and more to the point to fit in more information into a shorter amount of time. I think that would be better :)
First of all, great tutorial. I always wanted to learn typescript and this video helped me a lot. I do have one question. How do I implement knex into this? Like what folder should I put the knex stuff in?
Thanks for the video, this might be the most useful video on this topic. I have one question tho, I'm trying to test the API with Jest&supertest and I have a couple ideas about how to use the app (returned by the express() function) for the supertest requests, but I wonder your opinion. How'd you do it?
Thanks! To be honest I haven't done much in regards to testing so I wouldn't be able to answer that unfortunately. Definitely something I'll be looking into for the future though :)
Great work! I have a question though, how would you handle it if you had numerous fields in the req.body? Would you have list them all out and pass as parameters into the service class?
You should be able to use object destructuring like function create({ name, email, password}) and call it like create(req.body). However it's not something I've used that often in TypeScript so probably worth looking into it a bit more as you'll have to handle types! I think it would look something like this though, function create({ name, email, password} : {name: string, email: string, password: string})
i successfully got this working for me but not with the @/resources nor @utils option, i manually typed out the relative path, pls i need help fixing it
This is well suited for ex-PHP, C# or Java devs. Otherwise it's overly complicated. It's obvious you're not a JS-first programmer. I wouldn't recommend this tutorial to anyone whose background is just with JS or has no background at all.
wow! greatest video I've seen. What if I wanna have users and want these posts to be associated with users? In post create create({...req.body, userId: req.user.id}) doesn't seem to work.
Firstly make sure the route for creating a post uses authenticated middleware to populate req.user. Then you would need to add userId to the post model (I usually just call it user instead of userId), then in the controller you would need to pass in the user's id into the create function on post service and then in the create function in post service add another parameter for user and then use that in the post.create() function. Like this.post.create({ title, body, user }), hopefully that made sense :)
@@Rettson such a fast and well detailed response! have most of the things just like u described. I'll do minor tweaks and it should be fine. I have already created rest APIs but it's my first time using this approach! Thank you. Looking forward to seeing more tutorials from your Channel and seeing it grow exponentially
Hello Jason, thank you for putting up the great content. I have a question which I have been stuck on, when I try running the project, I get an error saying "cannot find the validateEnv file in list/index.js" do you have an idea as to why is coming up please?
Hi, had the same problem. Fix it by adding "@": "dist" in package.json { "_moduleAliases": { "@/resources/*": "dist/resources", "@/utils/*": "dist/utils", "@/middleware/*": "dist/middleware", "@": "dist" }
Hi Rettson, how re you. Excellent tutorial. The most complete Rest API with Typescript here. I would like that you passing a order, pagination and hateoas with this rest api. Is possible? Thank you so much!
Hi, thank you for the compliment! I may be able to cover some of your suggestions in this tutorial series however I have some ideas for some full stack projects that I think will definitely use the functionality that you suggested. I have a lot of videos planned so not too sure when I'll get around to making those so stay tuned! :)
@@steamaccount2276 You're actually already doing that if you followed along with the video. Alias paths are supported out of the box in TS but not in JS which is why we add the module alias package and add the aliases to package.json so that the aliases work in the JS that we get from transpiling TS. To get it working for plain JS you just need to install the module alias package and add the aliases to package.json.
Hi again! If you have a look at this controller from the user authentication video - github.com/JasonMerrett/nodejs-api-from-scratch/blob/master/src/resources/user/user.controller.ts - you can see in the initialise routes function it's doing this.router.get(). Works in the same way as a this.router.post() request but instead it uses the .get() function and will be called when you make a GET request. There's also .patch() and .delete() methods too!
@@Rettson Thanks! So once you've set up the controller, do you need to make any changes elsewhere or just invoke the .get request on the client side?? Also, in your repo, where is 'user' being parsed from on line 74? I'm a little confused on what this is doing: if (!req.user) { return next(new HttpException(404, 'No logged in user')); } res.status(200).send({ data: req.user });
Yeah you just need to make sure you are instantiating the controller in index.ts just the same as it's done in the tutorial and that should initialise all the routes you create in the controller you added and then after that you can send requests to them from your frontend. As for req.user, that is set earlier in the code. If you notice I'm using the "authenticated" middleware (github.com/JasonMerrett/nodejs-api-from-scratch/blob/master/src/middleware/authenticated.middleware.ts) for the request you're referring to. That middleware will look for the users authentication token, parse it and grab the user's ID from it, search for the user in the user's collection in MongoDB and assign the returned user to req.user. That then becomes available throughout the rest of the request so you can do req.user.name for example.
this is a really helpful video, but i am facing a challenge with the module-alias stuff it keeps giving me d error of module not found even after importing into the index.ts and d base url is also set Edit - It works now thanks.
great content. i have this `node dist/index.js node:internal/validators:120 throw new ERR_INVALID_ARG_TYPE(name, 'string', value); ^ TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Array ` error and have researched but seems its not common and there are less topics on it i neep help pls
@@Rettson it's showing a 404 error but in html format 😅 I did clone a clean code from your repository to test it and I got the same result... so I thinking about adding a another route for undefined routes. Or maybe there something wrong because it's not showing à json response for this case. idk
My solution to fix it : this.initialiseNotFoundRoutes(); in the class App All it's doing is throwing a HTTPException in the next function for all methods on * private initialiseNotFoundRoutes(): void { this.express.all('*', (req, res, next) => { next(new HttpException(404, `Can't find ${req.originalUrl} on this server!`)) }); }
Hey there! Great tutorial so far, first time messing around with back-end software - just coming to the end of setup but getting some linting error that I'm having trouble locating online so wasn't sure if it was a custom alteration we did: - Unknown options: env, parserOptions, rules - 'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead. - 'rules' has been removed. Please use the 'overrideConfig.rules' option instead. Any assistance appreciated!
Hey, glad you're enjoying the tutorial! I haven't seen the error you're mentioning before but I've been doing some looking into it and I'm wondering if it's something to do with the fact that eslint doesn't know where to look exactly because we're using TypeScript and not normal JavaScript. overrides: [ { files: ['*.ts', '*.tsx'], parserOptions: { project: ['./tsconfig.json'], }, } ], Here's a gist I made to show where that would go - gist.github.com/JasonMerrett/ec7558aafd4280423e31de0f047a5204 Have a try at adding that to your .eslintrc.js file and let me know if it works :)
@@GoodnightBng Yeah I have been thinking about creating something like a React app (Next.JS most likely) for this. Maybe using the code from this video and the next which focuses on user authentication as a starting point and building out a full stack application from there :)
@@Rettson100% - I'm a junior front-end dev looking to go full stack and I really like your style. Will certainly be keeping an eye on your channel. One thing I've never done is connect a db to a front-end so hopefully I can work it out from the user auth vid - will let you know! Thanks for coming back so fast too.
Hello! Hopefully you found this tutorial useful. All the code in the video is available on GitHub here - github.com/JasonMerrett/nodejs-api-from-scratch. Let me know if there's any specific topics you'd like me to cover in future videos of this series 😄
Hey tnx bro
Can you make a tutorial on how to setup ubuntu for development
It would be cool to see the blog finnished with a react front end and add an eCommerce section to it as well! I've been trying to find a good way to build m own website and I love how you involved typescript with express using classes!! And i'm currently building my site with this tutorial!!! Thank you!!!!
please add swagger-ui in this project :D
thank me later :P
finally class based express and TS. Thanks man
The methods implemented in this project are strictly best practices. I recommend using it. Thanks for sharing.
Hi brother! Your style and the way you follow while building this app is really beneficial and informative. I hope you can post more videos just like that. Wish you the best
Hello, great content 😮, please create more such a series on TS + Nodejs + Expressjs + Mongodb project topics if possible
It was a great and useful tutorial. Please don't stop. Continue this kind of video, like a master child or more complex content! thank you for sharing with us such a nice tutorial.
this great! I don't see many express projects having oop structure like this. Hope nodejs and oop contents appear more.
Thank you so much
Great video man its 10/10 what I needed so thanks for your help and I hope your channel grow.
This is what i'm looking for...great!!!!
Beautiful structuring and code style, thanks for the tutorial
Glad you like it!
Thank you for this video, it's well presented and exactly what I was looking for.
Tip for any other newbies whose HTTP request hangs indefinitely - turns out I missed calling the next() callback in my validation middleware, so the service code never executed (and hence never moved onto anything that triggered a res() response to reply to the HTTP client).
Love the OOP approach
this tutorial is so underrated.. keep up please!
wow awesome video! This is my 1st video and I instantly subscribed to your channel, man. Keep up and produce better and better video! 🔥
btw can you do a monorepo project? Especially using turborepo if you will, thank you in advance!
Thank you! Truth be told I've never used Turborepo but I've just had a quick look and it looks really good. I'm sure I can fit it into a future video :)
Thank god! This is what I was looking for! Thank you!
Hi Jason, your video is greatly helping me to get into web development, please keep it coming! I would be really happy if you could spare the time to answer two of my questions that came up while watching this video:
1. Can you explain why you are using async/await AND Promise in your controller file when it comes to handling the create method for instance. Is it best practice to define a return value here? And why exactly ""? Could I also use the Post interface as a response type here instead of ""?
2. This seems to be a really advanced approach, I wonder where I can find more information on MERN stack with OOP. Do you have any sources such as documentation or books that you could recommend?
Hi, glad to hear my videos are helping and good luck with your web development journey!
1. The reason why Promise is used is to indicate that this function is asynchronous and will run in the background unless you use something that will stop that. So if you called this.create() the rest of your code would continue to execute but you could also call it like await this.create() or this.create().then(). Essentially, even though it doesn't explicitly return a promise like you would see if you did "return new Promise()" it still technically returns a promise when using async/await. Having Promise as the return type acts as a sort of warning too as if we tried using the function synchronously it might not works as the developer expects! We use the Response interface because that's what we are returning "res.json({})" or void because we could also call next() which doesn't return anything. We don't actually return a Post object but instead include it as part of the JSON that gets returned from the res object.
2. I don't have anything specific to recommend as most of the books I have are quite specific and if you are just getting into web development I don't think they would be helpful just yet. There are lots of videos on RUclips from channels like TraveryMedia, JavaScript Mastery, Lama Dev to name a few.
Hopefully this helped!
Amazing video and amazing content.
Thank you!
Please keep it up.
It is a well structured, detailed video about Typescript. It helps me a lot. Brother kindly, if you enlighten about the product list, update and delete the product with image upload (normal or S3) , it will be very beneficial. Waiting for your valuable response.
Amazing video!!! This helped me alot.
Thank you bro for this amazing tutorial..
Great work !
I really like your style
Post more please ^^
Thank you for the compliment! Will have some more videos coming soon :)
Good tutorial, thank you!
Glad it was helpful!
Thank you for the tutorial, can't wait for the next episode. I'm a php dev and trying for the first time node as backend. It look very interesting. Can we use mysql or postgresql with node(express)? Thank again again
Hi, I'm glad this series is helping!
Yes you can use MySQL or PostgreSQL but you'll need to use an ORM library that supports them, TypeORM seems to be a popular choice. You should be able to do most things the same in regards to the code from this video but replace mongoose with TypeORM and use TypeORM for creating models. TypeORM has good documentation which should give you a good idea of how to replace mongoose. Hopefully this helped :)
Great, thanks for sharing.
best tutorial 😍
Thank you so much for that, It was really helpful. There is just one thing that I would recommend. I think you could explain a few more steps. Because sometimes you are just typing and typing and typing.......... If this is the case, you could do just like 30 minutes and share the git code. But please do not get me wrong, your video was very useful I really enjoyed that.
Thank you, I've noted your suggestion. Going forward I'll aim to do videos that are a bit quicker and more to the point to fit in more information into a shorter amount of time. I think that would be better :)
@@Rettson Thanks for replying to me, man. I will continue following your channel, that is a great channel. Keep Doing...
use chatgpt to explain the code if you do not understand its really helpful
First of all, great tutorial. I always wanted to learn typescript and this video helped me a lot. I do have one question. How do I implement knex into this? Like what folder should I put the knex stuff in?
Excellant tutorial
Nice Thank you so amazing content 🤞🤞😍😍👏👏👌👌🙌🙌✌✌🤩🤩
hi Is this video enough to learn TypeٍٍScript with Nodejs..I already know the basics of TypeٍٍScript
it`s good for setup if you have know nodejs & typescript
nice tutorial.. but you should use dependency injection in your framework..manually creating an instance is really PITA
Hey Rettson can we use ts-node and ts-node-dev instead of compiling using tsc btw great content keep it up
great video
Could you make a tutorial Node TypeScript and Prisma?
Hello ! Could you please add swagger integration as well .Thanks for the video.
Thanks for the video, this might be the most useful video on this topic. I have one question tho, I'm trying to test the API with Jest&supertest and I have a couple ideas about how to use the app (returned by the express() function) for the supertest requests, but I wonder your opinion. How'd you do it?
Thanks! To be honest I haven't done much in regards to testing so I wouldn't be able to answer that unfortunately. Definitely something I'll be looking into for the future though :)
Hello, one more question, when we write that a function returns a Promise, the error is returned in the catch when we throw it??
Great work! I have a question though, how would you handle it if you had numerous fields in the req.body? Would you have list them all out and pass as parameters into the service class?
You should be able to use object destructuring like function create({ name, email, password}) and call it like create(req.body). However it's not something I've used that often in TypeScript so probably worth looking into it a bit more as you'll have to handle types!
I think it would look something like this though, function create({ name, email, password} : {name: string, email: string, password: string})
great! tks so much
Glad it helped!
i successfully got this working for me but not with the @/resources nor @utils option, i manually typed out the relative path, pls i need help fixing it
This is well suited for ex-PHP, C# or Java devs. Otherwise it's overly complicated. It's obvious you're not a JS-first programmer. I wouldn't recommend this tutorial to anyone whose background is just with JS or has no background at all.
wow! greatest video I've seen.
What if I wanna have users and want these posts to be associated with users?
In post create create({...req.body, userId: req.user.id}) doesn't seem to work.
Firstly make sure the route for creating a post uses authenticated middleware to populate req.user. Then you would need to add userId to the post model (I usually just call it user instead of userId), then in the controller you would need to pass in the user's id into the create function on post service and then in the create function in post service add another parameter for user and then use that in the post.create() function. Like this.post.create({ title, body, user }), hopefully that made sense :)
@@Rettson such a fast and well detailed response! have most of the things just like u described. I'll do minor tweaks and it should be fine.
I have already created rest APIs but it's my first time using this approach! Thank you.
Looking forward to seeing more tutorials from your Channel and seeing it grow exponentially
great course, i'll use it as a wikipedia when i'm coding :v
Hello Jason, thank you for putting up the great content.
I have a question which I have been stuck on, when I try running the project, I get an error saying "cannot find the validateEnv file in list/index.js" do you have an idea as to why is coming up please?
Hi, had the same problem. Fix it by adding "@": "dist" in package.json
{ "_moduleAliases": {
"@/resources/*": "dist/resources",
"@/utils/*": "dist/utils",
"@/middleware/*": "dist/middleware",
"@": "dist"
}
Hi Rettson, how re you. Excellent tutorial. The most complete Rest API with Typescript here. I would like that you passing a order, pagination and hateoas with this rest api. Is possible? Thank you so much!
Hi, thank you for the compliment! I may be able to cover some of your suggestions in this tutorial series however I have some ideas for some full stack projects that I think will definitely use the functionality that you suggested. I have a lot of videos planned so not too sure when I'll get around to making those so stay tuned! :)
hi there is no index.js in my dist folder what did i do wrong??
Docker is not a needed for a .env file, for a beginning!
for newbie - iam understand "nothing" - chinese symbols.
At 10:16 you did @/resources stuff, is there a way to do the same thing with js?
As in get @/resources working in plain JS similar to how it works in TS?
@@Rettson yes, same working but for JS
@@steamaccount2276 You're actually already doing that if you followed along with the video. Alias paths are supported out of the box in TS but not in JS which is why we add the module alias package and add the aliases to package.json so that the aliases work in the JS that we get from transpiling TS. To get it working for plain JS you just need to install the module alias package and add the aliases to package.json.
@@Rettson thnx man 💝
Me again! Just a quick technical question, does this setup allow for GET requests or do you nee do set up a separate route / other file?
Hi again! If you have a look at this controller from the user authentication video - github.com/JasonMerrett/nodejs-api-from-scratch/blob/master/src/resources/user/user.controller.ts - you can see in the initialise routes function it's doing this.router.get(). Works in the same way as a this.router.post() request but instead it uses the .get() function and will be called when you make a GET request. There's also .patch() and .delete() methods too!
@@Rettson Thanks! So once you've set up the controller, do you need to make any changes elsewhere or just invoke the .get request on the client side?? Also, in your repo, where is 'user' being parsed from on line 74? I'm a little confused on what this is doing:
if (!req.user) {
return next(new HttpException(404, 'No logged in user'));
}
res.status(200).send({ data: req.user });
Yeah you just need to make sure you are instantiating the controller in index.ts just the same as it's done in the tutorial and that should initialise all the routes you create in the controller you added and then after that you can send requests to them from your frontend.
As for req.user, that is set earlier in the code. If you notice I'm using the "authenticated" middleware (github.com/JasonMerrett/nodejs-api-from-scratch/blob/master/src/middleware/authenticated.middleware.ts) for the request you're referring to. That middleware will look for the users authentication token, parse it and grab the user's ID from it, search for the user in the user's collection in MongoDB and assign the returned user to req.user. That then becomes available throughout the rest of the request so you can do req.user.name for example.
this is a really helpful video, but i am facing a challenge with the module-alias stuff it keeps giving me d error of module not found even after importing into the index.ts and d base url is also set
Edit - It works now thanks.
and you didn't tell us how you do it... sigh...
great content. i have this
`node dist/index.js
node:internal/validators:120
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Array
`
error and have researched but seems its not common and there are less topics on it i neep help pls
Same here, anyone got into this?
same 😢
Hey,
How do you handle not found routes ?
Express should throw a 404 error
@@Rettson it's showing a 404 error but in html format 😅
I did clone a clean code from your repository to test it and I got the same result... so I thinking about adding a another route for undefined routes. Or maybe there something wrong because it's not showing à json response for this case. idk
My solution to fix it :
this.initialiseNotFoundRoutes(); in the class App
All it's doing is throwing a HTTPException in the next function for all methods on *
private initialiseNotFoundRoutes(): void {
this.express.all('*', (req, res, next) => {
next(new HttpException(404, `Can't find ${req.originalUrl} on this server!`))
});
}
Nestjs styles huh
Hi, it might be similar but I've never used NestJS so I'm not too sure.
А чего так просмотров мало? хмм, ааа точно это же непросто ахх и не для начинающих, ну теперь ясно
Hey there!
Great tutorial so far, first time messing around with back-end software - just coming to the end of setup but getting some linting error that I'm having trouble locating online so wasn't sure if it was a custom alteration we did:
- Unknown options: env, parserOptions, rules
- 'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead.
- 'rules' has been removed. Please use the 'overrideConfig.rules' option instead.
Any assistance appreciated!
Hey, glad you're enjoying the tutorial! I haven't seen the error you're mentioning before but I've been doing some looking into it and I'm wondering if it's something to do with the fact that eslint doesn't know where to look exactly because we're using TypeScript and not normal JavaScript.
overrides: [
{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: ['./tsconfig.json'],
},
}
],
Here's a gist I made to show where that would go - gist.github.com/JasonMerrett/ec7558aafd4280423e31de0f047a5204
Have a try at adding that to your .eslintrc.js file and let me know if it works :)
@@Rettson thanks so much I’ll try it when I’m home! Is there anything in the works to link it up to a front end?
@@GoodnightBng Yeah I have been thinking about creating something like a React app (Next.JS most likely) for this. Maybe using the code from this video and the next which focuses on user authentication as a starting point and building out a full stack application from there :)
@@Rettson100% - I'm a junior front-end dev looking to go full stack and I really like your style. Will certainly be keeping an eye on your channel. One thing I've never done is connect a db to a front-end so hopefully I can work it out from the user auth vid - will let you know! Thanks for coming back so fast too.
@@Rettson yes please im waiting for that