Build a REST API with Node.js, Express, TypeScript, MongoDB & Zod

Поділитися
Вставка
  • Опубліковано 29 вер 2024

КОМЕНТАРІ • 438

  • @TomDoesTech
    @TomDoesTech  3 роки тому +35

    Learn how to test the REST API with the next video on the series: ua-cam.com/video/r5L1XRZaCR0/v-deo.html

    • @francisabonyi7115
      @francisabonyi7115 3 роки тому +3

      Thank so much for your effort, your courses are awesome.. Can you please add video for Redis cache on this video or another built project. Thanks

    • @ravenMK_
      @ravenMK_ 2 роки тому +1

      Man I love you already!

    • @kittisakphatchaiphongsa3177
      @kittisakphatchaiphongsa3177 2 роки тому

      @@francisabonyi7115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    • @Islam_Eliwa
      @Islam_Eliwa 2 роки тому

      you are amazing dude, thanks a lot

    • @TomDoesTech
      @TomDoesTech  2 роки тому +8

      ​@@stevechude3730 my videos are not for beginners. If you don't know hwo to set up Mongo locally, this video is not for you.
      Please consider how rude you're being to people that spend hours making videos for free.

  • @thiagocrux
    @thiagocrux 2 роки тому +55

    It's rare to find people who provide us with as much content as you do and even less with this quality. This video was immensely rich and I could learn a lot from it. Thanks, Tom!

    • @truthalwaysprevails662
      @truthalwaysprevails662 2 роки тому +1

      This is not to take anything away from Tom and his wonderful tutorials, the one thing I have began to observe is that lesser the subscriber count the better is the quality of the tutorial. Definitely not every time but generally

  • @jean-marcmockel7848
    @jean-marcmockel7848 2 роки тому +15

    Hey man! Outstanding value in these two hours. Thanks a lot for putting in the work. Can't wait to start the other videos in that playlist.
    One quick feedback from my side:
    You're kinda rushing through the tutorial and it's sometimes hard to follow in that pace. It would be great if you could explain certain things a little bit better like the overall architecture of the application and why you are doing certain things. I think it's always great to have the big picture from the beginning on.
    Keep up the great work!

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      Thank you for the feedback. It's difficult to tell what pace the video should be because it really depends on how much experience the viewer has I think.

    • @jean-marcmockel7848
      @jean-marcmockel7848 2 роки тому

      @@TomDoesTech Yeah I know what you mean. "Advanced" or "Beginner" is always subjective of course and a question what kind of audience you'd like to serve with your videos. More beginners or more advanced devs that might get bored out. But nonetheless, your content stays on a high quality! Thanks for your efforts, Tom.

  • @oz4549
    @oz4549 11 місяців тому +23

    I have said it before and I will say it again. This tutorial is so good that I got an internship. However, do not just copy and paste what he did here. Take this and build on it or build something different using the practices in this tutorial, connect a frontend to show something, or integrate other things if you need. When he said "it will make any CTO weak at their knees", he was not lying. But really understand what he's trying to teach here and I know there are issues with some packages being outdated but go and research, hell, use a different tool or whatever. That's how you get good. I will never be thankful enough to him for this tutorial, I learned a great deal of stuff. Thank you man!

    • @TomDoesTech
      @TomDoesTech  11 місяців тому

      This advice will land you a job, guaranteed

    • @minhnghia107
      @minhnghia107 8 місяців тому

      yah 2 years ago but still gold. I'm not going to intern yet but through this tutorial, my skills have improved. I decide to watch the tutorial and then redo it by myself :D

    • @ochogwuemmy8171
      @ochogwuemmy8171 6 місяців тому

      Great. But how do users login as there no route for login

  • @adriantworek1057
    @adriantworek1057 3 роки тому +7

    You do awesome job Tom providing such a robust content for free! Would like to see another part with creating UI, handling all these sessions etc. on the client side, preferably with Redux Toolkit or Context API.

    • @TomDoesTech
      @TomDoesTech  3 роки тому +5

      Thanks Adrian, I am working on the UI part. I'm going to keep the library use to a minimum because it could get confusing for anyone that doesn't know how that library works.

  • @hasanerken9604
    @hasanerken9604 3 роки тому

    This is a very good and thorough explanation of how to implement TS on REST Api. Great video. I hope we will see a video on Fastify as well. Thanks Tom, for this great tutorial.

  • @JeffLevyForPresident
    @JeffLevyForPresident 2 роки тому

    Senior dev here. Like. Senior. Anyway, I've been mucking about for a few months porting an ancient (most of you were in grammar school when line 1 was laid down) PHP project over to Node. I've got quite a good grasp on node, but as we programmers are bent to do, we strive for different, better. I've never been quite satisfied with my port of this project. I decided to scrap what I think I know, and start anew. This 2-hour video is solid gold. A great, fresh, modern approach. Well done. Great structure, great pacing. Whilst not the audience you intended for this video, I find that I am able to easily pause the video, and consider my implementation vs. yours, and adapt my system in near-realtime. Outstanding work.

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      I'm so glad you liked it! I think your approach is the best way to get the most out of the video. I try not to be too prescriptive in my videos. there are often better ways to do it. My goal is usually to give a suggestion and hope that the viewer pauses it and considers if they could improve on it. Thanks again for your kind words, I really appreciate it.

  • @Plaswin
    @Plaswin Рік тому

    Thank you so much, love how clean your code looks

  • @mssafy2592
    @mssafy2592 8 місяців тому +1

    man this was a master piece !

  • @belkocik
    @belkocik Рік тому +1

    I love your tutorials!

  • @siyanbolafaruk3005
    @siyanbolafaruk3005 Рік тому +1

    Thank you for creating this

  • @sreekumarmenon
    @sreekumarmenon 2 роки тому +2

    Awsome videos! suggestion for next video - Build a REST API with Node.js, Express, TypeScript, Prisma & Postgres.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      I did something very similar to this but I used Fastify instead of Express.

    • @sreekumarmenon
      @sreekumarmenon 2 роки тому

      @@TomDoesTech Awesone,, could you share the link pls

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      @@sreekumarmenon ua-cam.com/video/LMoMHP44-xM/v-deo.html

    • @sreekumarmenon
      @sreekumarmenon 2 роки тому +1

      @@TomDoesTech Thanks I like the folder structuree in that video better, controller,service,schema all in same folder grouped by feauture! question why pick zod over yup ?

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      @@sreekumarmenon Zod has better TS support than Yup

  • @swayamnayak7134
    @swayamnayak7134 2 роки тому +2

    Great video tom !! Can you please make a video on how to use typeorm with this server to interact with a sql database..

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      Thanks, who's Tim?

    • @swayamnayak7134
      @swayamnayak7134 2 роки тому +1

      @@TomDoesTech ohh sorry i mispelled tom as tim 😅

  • @janxavier8264
    @janxavier8264 Рік тому +3

    "Make any CTO weak at the knees" 😆

  • @nelsonfleig5024
    @nelsonfleig5024 2 роки тому +2

    Thank you so much Tom. This is excellente! What do you think about recreating this with Type-Graphql and Apollo? Seems to be a great stack for building modern graphql apps with Typescript.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +5

      Yeah, I really like TypeGraphQL and have used it a fair bit so I think I will make a tutorial on it.

  • @devsami
    @devsami 2 роки тому +3

    Hi, I watched your previous vidoe on the same, I liked this video far more than the previous, because in this session, we end user get to see and comprehend the code written, and it's not overwhelming when you explain by writing them.
    I was practicing it alongside, although I am getting type errors like "module mongoose has no exported member DocuemtDefinition"
    Can you please help me with that?
    Also, Is there another way to use the interface instead Omitting each field individually

  • @andresbreuer
    @andresbreuer Рік тому

    Beautiful Tutorial!!! LOVED IT!! Just one question... Why do you prefer to use the config file for variables instead of enviroment variables? Is that secure?

    • @TomDoesTech
      @TomDoesTech  Рік тому +1

      These 2 things aren't mutely exclusive. The con fig file has defaults which can be overwritten by env vars

  • @zackOverflow
    @zackOverflow 2 роки тому

    This is awesome!!! thank you for this lesson. One request, can we make it a full stack app i.e. can we build a frontend to consume this API? thank you once again.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      There is a UI part in this series if you want to check that out

    • @zackOverflow
      @zackOverflow 2 роки тому

      @@TomDoesTech ok, thanks so much. Meanwhile, i'll like to point out that, both your terminal & your file EXPLORER cover more than half of the screen in this video, it would be nice if you minimize your terminal when not in use that way, the viewers can have a clear view of the code on the screen. Thank you, you are the best.

  • @spm2.o24
    @spm2.o24 3 роки тому +2

    next should be test with jest and google auth please

    • @dammyola
      @dammyola 3 роки тому +1

      I can't wait for that as well

    • @TomDoesTech
      @TomDoesTech  3 роки тому

      The testing video is in progress. I do have a video on Google OAuth already but it's not fantastic, so I could do another one.

  • @swistek00
    @swistek00 Рік тому

    i donno how its work on your video but i need to change evry query on product controller from productId to _id : productId ; great video thanks you!

    • @TomDoesTech
      @TomDoesTech  Рік тому

      _id is an id put onto the object by MongoDB. productId is something we put on there. You should be able to query by either

  • @politeboy2996
    @politeboy2996 2 роки тому

    Amazing codding standard

  • @adventurer2395
    @adventurer2395 2 роки тому

    What would you call the architectural pattern you follow in this project, and why not abstract the database to make it easy to swap if needed?

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      I'd call it a 'TomDoesTech special architecture', nah it's MCS or something, Model Controller Service.
      Why would I abstract the database? This is a tutorial, not an application I'm deploying. But who just rips out their BD and swaps it for something else? It's not something I've ever seen happen. Not without a major rewrite anyway.

  • @leojohn6702
    @leojohn6702 Рік тому +1

    Question. Instead of config file, why you dis not used .env?

    • @TomDoesTech
      @TomDoesTech  Рік тому +1

      I put secrets in a .env file, otherwise it's convenient to have defaults hard-coded

    • @leojohn6702
      @leojohn6702 Рік тому

      @@TomDoesTech aaa. I understand. Thank you for the video. Learning something new.

  • @adamsackfield589
    @adamsackfield589 2 роки тому +1

    Hi loving the content. I’m having an error at the 51:00 mark with the user._id error is relating to can’t cast object to string.

    • @thiagoroberto7891
      @thiagoroberto7891 2 роки тому +1

      Man, me too. I found a comment that say that we can replace "return omit(user.toJSON(), 'password');" to "return omit(user.toObject(), 'password');" at user service

  • @daniel_does_development
    @daniel_does_development 8 місяців тому

    I built a front-end to connect to this API and it works really well. However I think I did something wrong with the deserializeUser middleware and have no idea how to fix it as my code looks the same as yours. When I create a session and the routes function as expected, but when the access token expires, the refresh token does not decode the user and store it in the locals object of the app, so I am forced to create another session to continue using the API. Do you have any idea what I am doing wrong?

    • @ochogwuemmy8171
      @ochogwuemmy8171 6 місяців тому

      How do you make user to login in your app because there no routes for login

    • @daniel_does_development
      @daniel_does_development 6 місяців тому

      The createUserSessionHandler for the ‘/api/sessions’ route logs users into the app.
      I also found the problem I was having, I did not change the refresh token time till expiry, so it was becoming expired at the same time as the access token. 🤦🏽‍♂️

    • @ochogwuemmy8171
      @ochogwuemmy8171 6 місяців тому

      Ok that is great and many thanks. Will update you my progress, meanwhile what platform did you used to generate your public and private keys?. I use window
      @@daniel_does_development

  • @adembaccara4805
    @adembaccara4805 2 роки тому

    33:23 why did you use async with hashSync , it seems that has no effect

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      Yeah, I just looked at the docs and it doesn't return a prom ise, no need to use await here, my bad

  • @irahazda
    @irahazda Рік тому

    In your createSession function, where does the _id property come from. Because when I'm trying to access session._id in accessToken and refreshToken, I keep getting an error

  • @muthukumarkamatchi1895
    @muthukumarkamatchi1895 2 роки тому

    It's huge helpful for me. But how to list all the products. Kindly let me know asap

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      Make a GET endpoint that returns all the products?

    • @muthukumarkamatchi1895
      @muthukumarkamatchi1895 2 роки тому

      @@TomDoesTech Thank you for your response. I find out the solve.

    • @muthukumarkamatchi1895
      @muthukumarkamatchi1895 2 роки тому

      How to make a GET endpoint with two Params. For example one find is using id and second find is using product name

    • @muthukumarkamatchi1895
      @muthukumarkamatchi1895 2 роки тому

      Kindly please help me

  • @erictam3349
    @erictam3349 Рік тому

    with TDD please?

  • @karthikpuvvula
    @karthikpuvvula 11 місяців тому

    thanks a lot for the video. but im not able to run "npm run dev":
    > express_ts@1.0.0 dev
    > ts-node-dev --respawn --transpile-only src/app.ts
    [INFO] 09:17:43 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 5.2.2)
    Compilation error in D:\Karthik\Documents\Playground\express_ts\src\app.ts
    [ERROR] 09:17:44 ⨯ Unable to compile TypeScript:
    error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left unspecified) when option 'module' is set to 'NodeNext'.

    • @karthikpuvvula
      @karthikpuvvula 11 місяців тому +1

      to anyone who's facing this issue. replace scripts in package.json
      "scripts": {
      "dev": "nodemon src/app.ts",
      "start": "ts-node src/app.ts"
      },

  • @graysonvirtue4058
    @graysonvirtue4058 2 роки тому

    If you're including the access and refresh token with every request, doesnt that negate having two tokens in the first place?

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      no?

    • @graysonvirtue4058
      @graysonvirtue4058 2 роки тому +1

      @@TomDoesTech what i mean is why not use the refresh token on its own? If it's included with every request to refresh the Access token if necessary, why not forgo the Access token? If someone has gained access to the Access token, they're going to have access to the Refresh Token as well.

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      @@graysonvirtue4058 You could do that, but the access token allows the session to be stateless for the life of the access token. So for the 15 minutes or so that it lives, you don't need to make a DB call to make sure their session is still active.

  • @nikolam-dev
    @nikolam-dev 3 роки тому

    What app do you use to graph the flow of the app?

    • @TomDoesTech
      @TomDoesTech  3 роки тому +2

      Whimsical. It's so good, I use it all the time. whimsical.com

  • @zahid8566
    @zahid8566 2 роки тому

    bookmark 41:56

  • @user-xv1gz8bd1d
    @user-xv1gz8bd1d 2 роки тому

    Session Controller : 58:00

  • @alright83
    @alright83 2 роки тому

    [ @1:11:51 of your video ] Hi Tom, in the session controller, can I ask why we need to store the user object, as well as the session._id in the refreshToken JWT? Will it not suffice to just store the session._id in the refreshToken? We are storing all the session ID in the database anyway.

  • @gorutorot
    @gorutorot 2 роки тому

    I've followed this tutorial down to the last detail and for some reason my get sessions route still returns forbidden, has anybody else encountered this issue?

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      Did you select an environment in postman?

    • @JWClark-vx2vw
      @JWClark-vx2vw 2 роки тому

      ​ @Cody Hayes For me, I had to set new environment from the environments tab on the left, then in the workspace on the top right I had to pick the environment I just created.

    • @chukaezem6267
      @chukaezem6267 Рік тому

      @@JWClark-vx2vw Or your accessToken may have expired. Remember its valid for only 15 minutes.

  • @АлМ-ы8ъ
    @АлМ-ы8ъ 2 роки тому +1

    you make it hard

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      make what hard?

    • @АлМ-ы8ъ
      @АлМ-ы8ъ 2 роки тому

      @@TomDoesTech model, schema, service, middleware... and all this just for user registration? I agree just need a model for the DB and middlewar for data`s validation

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      @@АлМ-ы8ъ So you don't think you need a controller or a service? Where would you put that login? In the model?

    • @АлМ-ы8ъ
      @АлМ-ы8ъ 2 роки тому

      I won’t tell you about the controller, I know why it is needed (although we can combine the logic of the controller and the service logic in one file).... Tell me, why do we need 2 separate files for validation (middleware and schema)?

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      ​@@АлМ-ы8ъ ​The validation middleware runs the schema to make sure the pyload passes that schema. You can then define a different schema for each route. Are you suggesting you put the schemas in the same file as the middleware? I don't understand exactly why you think it's overcomplicated. You said there were too many files then you said you understand why pretty much all of them are needed.
      I'm happy to clarify why you would need each file but if you're just going to leave a rude comment without even knowing what you're talking about, I'm not going to give you much time.

  • @zlackbiro
    @zlackbiro 2 роки тому +2

    You unnecessary overcomplicated entire project so hard! Why people need to overengineer simple things, i never understand that! 7 layers for nothing. If yo want to write bloatware, just learn from this tutorial.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +3

      If you don't understand how to write clean production-grade applications, that's fine but don't then come complain on a video that isn't for junior developers.

  • @ThisClark
    @ThisClark 2 роки тому +6

    If you got stuck with 403 forbidden in Postman around 3:30 in the video, set environment variables and attach the environment to the current workspace. Here's a one minute demo of me going from 403 forbidden to 200 ok by setting the environment properly: ua-cam.com/video/SRX8H7OMS0c/v-deo.html

  • @kylegeib9161
    @kylegeib9161 2 роки тому +3

    Anyone who wants to debug this program can add this script to their package.json:
    "dev:debug": "ts-node-dev --respawn --transpile-only --inspect=9229 src/app.ts"
    Run with `yarn dev:debug`
    And in your project's root dir add ./.vscode/launch.json and add the following configuration:
    {
    "configurations": [
    {
    "name": "Attach to dev:debug (w/ restart)",
    "port": 9229,
    "request": "attach",
    "skipFiles": [
    "/**",
    "node_modules/**"
    ],
    "type": "node",
    "cwd": "${workspaceFolder}",
    "restart": true
    }
    ]
    }
    Launch it from the dropdown on the debug panel. Should restart the debug hook when the server restarts on changes.

  • @iroekyjHD
    @iroekyjHD 2 роки тому +8

    If anyone else gets the *PinoWarning: prettyprint is deprecated* error use this code instead of the logger
    ```
    const transport = pino.transport({
    target:'pino-pretty',
    options: { colorize: true}
    })
    const log = pino({
    base: {
    pid: false
    },
    timestamp: () => `,"time":"${dayjs().format()}"`
    }, transport );
    export default log
    ```

    • @mikejnrr
      @mikejnrr Рік тому

      Thanks man. Saved me some minutes.

    • @dogepuresi
      @dogepuresi 9 місяців тому

      thanks man

  • @JWClark-vx2vw
    @JWClark-vx2vw 2 роки тому +2

    nanoid@4.0.0 was installed from yarn at the time of writing this comment. It didn't work, so I had to downgrade to match your repository with yarn upgrade nanoid@3.1.30

  • @wzup23
    @wzup23 2 місяці тому +1

    Whoa didn't know that I can use postman like this. I always manually type my input whenever I test O_O. Yes, horrible! Thanks for this dude! Will be checking on your other videos.

  • @Matiast9477
    @Matiast9477 5 місяців тому +1

    If you're having problems with the pino logger config because of the deprecated prettyPrint prop
    import logger from "pino";
    import dayjs from "dayjs";
    const log = logger({
    transport: {
    target: "pino-pretty",
    options: { colorize: true },
    },
    base: {
    pid: false,
    },
    timestamp: () => `,"time":"${dayjs().format()}"`,
    });
    export default log;
    this is the config

    • @improving_cow
      @improving_cow 5 місяців тому

      THANKS BUDDY for this solution

  • @ayushpaharia5452
    @ayushpaharia5452 3 роки тому +8

    Would love to see Prometheus, caddy+docker and Jest testing.
    Really got into typescript watching your videos.
    Please keep creating this lovely content!

    • @TomDoesTech
      @TomDoesTech  3 роки тому +1

      I'm working on testing with Jets now, it will be out nest week, Prometheus should be quick so I will do that too :)

    • @TomDoesTech
      @TomDoesTech  3 роки тому +2

      I also have a video about caddy + docker here: ua-cam.com/video/2oNsjyaCIrI/v-deo.html

  • @tenzl
    @tenzl Рік тому +2

    Hi Tom thanks for the video. Just a question on 1:35:18 why are we checking to see if there is no "_id" field in the decoded object? wouldn't it always be there if verifyJwt returns the decoded object?

  • @marcus_leon
    @marcus_leon Рік тому +2

    1:40:15 reIssueAccessToken is returning string or false, change the "return false" inside reIssueAccessToken to return "" , just a quick fix but can be fixed in many other ways

  • @defaulthaes7840
    @defaulthaes7840 10 місяців тому +2

    lots of mongoose type is outdated.

  • @pankaj_9998
    @pankaj_9998 9 місяців тому +3

    This channel is gold for nodejs reactjs devs. Thanks so much such valuable content 🙂

  • @zilvinas5130
    @zilvinas5130 2 роки тому +5

    Overal great tutorial, one improvement I would suggest is putting more attention in small mistakes you make and fix during speed-up. Followed halfway through the tutorial to get my project's template to where I feel comfortable to develop it on my own.
    Huge thanks for for providing great starting point with a manageable folder structure and other methodologies!

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      Thank you for the feedback, that's really helpful! When I make those mistakes, I stop talking while I try figure it out so I need to learn to keep talking and explain the issue.

    • @stevereid636
      @stevereid636 2 роки тому +1

      I agree, this is great tutorial, but you need to make sure to let us know when you’ve made a correction that been edited out. 🙏🏾 Otherwise excellent work👍🏾

  • @techOtuts
    @techOtuts 3 роки тому +2

    Thanks for the wonderful tutorial. Please make a video on how to securely handle refresh token and access token on the frontend with react. I need this for a job please

  • @edward8064
    @edward8064 2 роки тому +2

    Can anyone please explain what is the meaning of "req: Request" in the user.controller.ts file? Or maybe point me to the doc of the API. I'm new to Typescript and never saw someone modify the Express Request type.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      It means you're telling express what you expect in the request body

    • @edward8064
      @edward8064 2 роки тому

      @@TomDoesTech Oh okay. I get it. Thankyou for the response from Indonesia!

  • @jessejulian9069
    @jessejulian9069 Рік тому +1

    Hey Tom, I keep getting this error when I run the Create Session Request from Postman despite using this resource you linked in a comment below for generating keys. I've already tried generating different key sizes
    Error: secretOrPrivateKey must be an asymmetric key when using RS256

    • @jessejulian9069
      @jessejulian9069 Рік тому +1

      I realized my mistake. I needed to push my public and private keys all the way to the left margin of the code editor. No indents allowed (Not even formatting Indentations). Also you need to generate RSA Keys of 2048 bit size . GOODLUCK

    • @vina-official2574
      @vina-official2574 9 місяців тому

      Me too@@jessejulian9069, I have this problem too and still stacking with this issue.

  • @kimshares1487
    @kimshares1487 2 роки тому +2

    Thankyou I got a job and this is what I am using to learn the TypeScript perspective of Express. Kudos!

  • @raoufsatto889
    @raoufsatto889 2 роки тому +1

    hello I in 40:07 minute I face this error: Module '"mongoose"' has no exported member 'DocumentDefinition'.ts(2305)
    any help pls?

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      Hi Raouf, I created a video showing how to fix this issue: ua-cam.com/video/5-1KuU-21uI/v-deo.html

  • @johnterriee7224
    @johnterriee7224 Рік тому +1

    error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left unspecified) when option 'module' is set to 'NodeNext'.
    got this error when trying to run npm run dev to run the app.ts file
    any help??

    • @TomDoesTech
      @TomDoesTech  Рік тому

      what did you try?

    • @mladendubovac
      @mladendubovac 9 місяців тому

      Don't know if you found a way or not, but for anyone else having this issue, you just need to update "module" to "NodeNext" and "moduleResolution" to "NodeNext" inside tsconfig.json

    • @johnterriee7224
      @johnterriee7224 9 місяців тому

      yes i found a way... thank you@@mladendubovac

  • @alanmejia6375
    @alanmejia6375 3 роки тому +3

    You are great! Please make a video with full testing and React with TS. Well, Docker too! jaja

    • @TomDoesTech
      @TomDoesTech  3 роки тому +1

      Thanks! I am working on the testing video now :)

  • @filipkajanovic1425
    @filipkajanovic1425 7 місяців тому

    Hello there! First of all, I realy love your tutorial(s).
    I'd like to ask little bit deeper about session handling =>
    We are making new session every time user logs in. In longer term i feel like it's lot of unnecessary data in db so my questions are =>
    1) Should we reuse users preivouse session, or is that bad approach?
    2) Should we keep them or would it be better to have some middleware that would once in time delete or old sessions? Or delete users preivouse session every time he logs in...?
    3) Can we use them for storing history of users behavior? (Add new variable to Sessions & have some middleware that would push log that variable every time some endpoint is called from that session)
    Thank you & hope you're doing well 🙂

  • @SuperSpawn92
    @SuperSpawn92 8 місяців тому

    "prettyPrint" gives me an error that it does not exist, also if anyone has error for 'moduleResoluion' before adding tsconfig.json you should create that file and put this in compilerOptions: "module": "NodeNext", "moduleResolution": "NodeNext"...

  • @imigi427
    @imigi427 Рік тому +1

    If someone had problem with: 'routines: get_header_and_data: bad end line', just check if your IDE do not add extra line while saving your document. In my case, 'prettier' extension added extra spaces on the beginng of every line. After correcting that I got my token keys.
    BTW. Thank You TomDoesTech for your yt tutorial ts with my node server. And your video is god blessing

  • @RomainBARRAUD
    @RomainBARRAUD 5 місяців тому

    I keep on receiving Error: secretOrPrivateKey must be an asymmetric key when using RS256. Has anyone faced the same?

  • @AesSedai2020
    @AesSedai2020 3 місяці тому +1

    Can I say I absolutely love your tutorials, I am learning so much! Thank you :)

  • @user-oz3hc6lj2e
    @user-oz3hc6lj2e 2 місяці тому

    don't use ts-node, it doesn't support es module.
    instead use tsx which is lightweight and very easy to use
    and use helmet js,

  • @axelpaul8988
    @axelpaul8988 2 роки тому +3

    I love your channel and the tutorials you created. They are very helpful! It would be great if you could zoom in vscode with some software for zooming videos so it is easier to understand what's going on since I usually divide my screen in two pieces. One is the video and the other one is my IDE and when I do this, the characters from your IDE are pretty small. Overall, I love the channel and I'm very happy that you are getting more subscribers every day.

  • @Skia_
    @Skia_ 3 роки тому +7

    Hello, i have a question regarding the folder structure
    What's your thought on the feature oriented structure?
    (Where one would have a top level folder for Users, Products and each of those contain the corresponding controller, service and model etc)
    Wouldn't that make it much easier to manage especially when your app grows in size?

    • @dammyola
      @dammyola 3 роки тому +3

      I'm interested in the answer for this question as well, thanks for asking.

    • @TomDoesTech
      @TomDoesTech  3 роки тому +7

      Hi Skia, thanks for the question. The answer to this is going to be a little long, so sorry for that.
      The module approach has become really popular, especially with Nest.js using it. I think it's a great approach but not really something I use outside of Nest.js.
      Firstly, it doesn't really matter what you use, just be consistent. People will choose weird hills to die on and tell you one thing is absolutely better and another, I tend to be very skeptical of opinions like that.
      The module approach that you mentioned in a tip of the hat to OOP where everything is organised around object definitions. OOP isn't a paradigm that I use often, or at all outside of Next.js. I like to organise my code around functions and think more about how the data flows through the system, opposed to how objects are defined.
      Lastly, this structure helps to illustrate how the data flows from the route handlers, through the controller and down to the DB, which I think it an important concept to think about and teach.

    • @TomDoesTech
      @TomDoesTech  3 роки тому +8

      I'll also add that when it coming to maintaining large code bases, I rarely think about how the code is actually organised, as long as it's consistent. The other things that also help maintain large code bases are good tests, documentation, small and simple components, appropriate abstractions ect...

  • @nicklansbury3166
    @nicklansbury3166 3 роки тому +9

    I love how you _almost_ stopped yourself laughing at your CTO comment right at the beginning. Thanks for putting together what will no doubt be another excellent tutorial. Keep 'em coming.

    • @TomDoesTech
      @TomDoesTech  3 роки тому +3

      I thought about that joke for way too long.

  • @eissa178
    @eissa178 2 роки тому +1

    It would be top if you can make a new video, adding a new endpoint but this time using a TDD approach. This way, we could learn how an experienced developer writes code using TDD.

  • @HighGamingDifficulty
    @HighGamingDifficulty 2 роки тому +2

    Love your tutorials, I am a beginner with TypeScript, it helps a lot, thank you!

  • @codevo6738
    @codevo6738 2 роки тому

    Please is there a reason why you were storing the user's sessions in the database? Also, can I store the user's sessions in Redis instead of the database?

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      It's stored in the DB so we can check that it's still valid when we go to issue a refresh token.
      Storing it in Redis would is a good idea.

  • @sarcasticdna
    @sarcasticdna 2 роки тому +2

    One good practice
    In Schema in usermodel add this field
    {
    ...something
    select:false
    }
    this will not return password unless we require by this method we can use less lodash
    to get it use .populate("password") in the end of query

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      That's awesome! Thanks for the tip.

    • @mattari97
      @mattari97 2 роки тому

      awesome. @TomDoesTech you should pin that comment. Thank you for the great tutorial

    • @TomDoesTech
      @TomDoesTech  2 роки тому

      @@mattari97 It doesn't work, or at least I can see it causing issues. If you do select false, it won't show up in the validation function.

    • @mattari97
      @mattari97 2 роки тому

      @@TomDoesTech export async function validatePassword({ email, password }: { email: string; password: string }) {
      const user = await UserModel.findOne({ email }).populate("password");
      if (!user) return false;
      const isValid = await user.comparePassword(password);
      if (!isValid) return false;
      return user.depopulate("password");
      }

    • @mattari97
      @mattari97 2 роки тому

      @@TomDoesTech the problem is that you need to "populate" the password in the findOne method from "mongoose" or it's undefined in the comparePassword instance method. see the fix above.

  • @durveshparmar6775
    @durveshparmar6775 Рік тому +1

    Hey that was great work and the one I was looking for... But I couldn't figure out how to generate refresh token private / public keys? is it same as access token private / public key process or different?

    • @TomDoesTech
      @TomDoesTech  Рік тому +1

      You can use the same or different keys, up to you. Probably better to use different keys but it's not that big of a deal

  • @osanyinbiyusuf7308
    @osanyinbiyusuf7308 2 роки тому +1

    I cant believe i have access to this kinda tutorial for free....the amount of knowledge passed here is quite overwhelming.....I appreciate you so much.....your tutorial has great impact in my life...Many thanks.

  • @aarondiaz2506
    @aarondiaz2506 Рік тому +1

    super high quality content! I really like that you explain things like currying on the go, i mean you don't let anything unexplained on your code, thank you.

  • @RaydenNnN
    @RaydenNnN 2 роки тому +2

    just one tip, use status on your tutorials ;)
    forget to use 201 to create a new user, create sessions, etc

  • @caglaryldz5987
    @caglaryldz5987 2 роки тому +1

    I love your code. It is very well prepared and the structure is perfect. However, I would like to point out a few things. You are like rushing by not telling why you are doing what you are doing.
    As an example, I could not understand why would we need jwt to have two tokens. Why can't we use only one? Doesn't it bring more effort? Plus I see that we are not updating the refresh token.
    Also when you say "decoded = user", I never understand that kind of naming.
    I am not a great dev and I am only developing a backend app by looking at your code, so please correct me if necessary.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      This tutorial is not meant for absolute beginners. If you want to understand the concepts behind refresh tokens, I have a video on that.

    • @caglaryldz5987
      @caglaryldz5987 2 роки тому

      ​@@TomDoesTech I am developing an application. I wanted to follow your style but let me ask you this.
      I have watched your other video on refresh and access tokens. There are two things I wonder about, one is If users can mess with the access token, why can't they mess with refresh token? And how does it make it more secure?
      The second question is when I create the token, how can I give access to a specific device so that only one device will be registered?
      Thank you for your previous response

  • @ravenMK_
    @ravenMK_ 2 роки тому +1

    Just exactly what I'm looking for and then there is you. I was meant to find you. Perfect timing. Thank you for this

  • @PsychoDude
    @PsychoDude Місяць тому

    Why do u use a config instead of .env?

  • @notsure8175
    @notsure8175 2 роки тому +1

    thx man!
    can you tell something about yourself? i mean how long you have been programming, are you working as a programmer right now? what's your position/role if so

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      I've been coding professionally for about 9 years or so. I working as full stack developer now

  • @solyridz3
    @solyridz3 7 місяців тому

    I found it hard to understand is it session based authentication or token based one? I guess it is hybrid, because we use both session storage and access/refresh tokens. Is it some kind of hybrid approach?

    • @TomDoesTech
      @TomDoesTech  7 місяців тому +1

      It's kind of hybrid. You get the statelessnes of JWTs for 15 mins or so, but you also get the safely of sessions (you can delete sessions)

  • @kylegeib9161
    @kylegeib9161 2 роки тому +2

    Note to self: at 50:54 don't pause and run the request yourself and wonder why your code hangs and spend 20 minutes trying to find a solution only for the video to find it 15 seconds later.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      I do worry about people doing that. I think the best thing to do is watch a bit, then go back and code it yourself, using the video as a guide when you get stuck.

    • @kylegeib9161
      @kylegeib9161 2 роки тому +2

      @@TomDoesTech Well, I very methodically followed this video and the one on testing. Then did it all again from memory with the original project as back-up reminders. Wrote comments for everything. Wrote my own explanations in a readme. Then took this knowledge into a senior engineer technical interview with a large telecom company where the subject was to "build a REST API" and basically just did this. Combined with my previous work experience and own projects I got a job offer. Haven't been fit into a team yet, so, I'll post an update when I do (and send you a big Kofi).

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      @@kylegeib9161 Congratulation! Awesome work

    • @kylegeib9161
      @kylegeib9161 2 роки тому +1

      @@TomDoesTech Didn’t take an offer with them (T-Mobile) but decided to become the third engineer for the new tech team at a growing educational company named Tutored by Teachers. Less pay but much more exciting material and an opportunity to learn a lot (I’ll be working directly under a very talented engineer and am very excited to learn from him). Also, working for a mission to teach children and provide an extra source of income for teachers around America seems like a very worthy thing indeed!

  • @James-ud7ys
    @James-ud7ys 2 роки тому +1

    Is there a reason to use the routes function instead of express.Router()? Traditionally, I've seen the Router method used but wanted to know your thoughts. Great vid!

    • @TomDoesTech
      @TomDoesTech  2 роки тому +1

      It's just the way I'm used to doing it. I've used the express.Router() in another video

  • @kiefer8101
    @kiefer8101 Рік тому +1

    Great video! More Express, TS, Prisma content pls!

  • @KennedyOtisNyaga
    @KennedyOtisNyaga Рік тому +1

    Very educative and thanks for taking time to make these production level videos. Also another tip on omitting the password from response... one can add select: false in the model level. This will automatically omit the password field or any other field with select: false.

  • @gotmorris
    @gotmorris 3 роки тому +2

    I would like to see more about testing the API. Thanks

  • @vladimirvucetic4466
    @vladimirvucetic4466 3 роки тому +1

    Hi thank you for great series.
    With this session/refresh token implementation should we care about stealing refresh token?
    Do you think that implementing refresh token rotation is overhead with your approach?
    Thanks

    • @TomDoesTech
      @TomDoesTech  3 роки тому +2

      Firstly, I'm not a security expert, I'm just demonstrating concepts here so if you're working with a lot of user data, make sure you have someone who understands security in-depth look at your code.
      Yeah, you should be worried about someone stealing the refresh token because if they have that, they can get an access token and then have access to the system.
      I would spend my effort trying to prevent the token from being stolen before I spend time reducing the blast radius in the event it does get stolen. So, what I mean by that is make sure you figure out how your application could be vulnerable to XSS attacks and reduce those threats.
      As for rotating refresh tokens. The issue is that you have no way to invalidate the refresh token without changing the public and private key pair. A lot of large companies will rotate their keys, but getting this to work without impacting the user experience would be challenging.

  • @leiayuri
    @leiayuri 2 роки тому +1

    Hi, Tom.
    By 31:36 when you are typing a userSchema.pre("save", async function(next: mongoose.HookNextFunction) The HookNextFunction does not show as a option. My "mongoose": "^6.4.0". For while did not find anything about that on google stackoverflow..... Could you please tell me a diferente way?

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      Yeah, it's been removed from Mongoose 6+. You can omit it and infer the type

    • @leiayuri
      @leiayuri 2 роки тому

      @@TomDoesTech Wow... thanks very much for the fastes reply ever.

  • @ashutosh887_
    @ashutosh887_ Рік тому +1

    Can't prettify timestamp with pino-pretty . Please share some resources for newer version

  • @clutchmadness
    @clutchmadness 2 роки тому +2

    I think this is the first time in my 'young' career that I've seen routes being handled like that. It's beautiful.

    • @TomDoesTech
      @TomDoesTech  2 роки тому +2

      So glad you like it :)

    • @christopherugochukwu3517
      @christopherugochukwu3517 Рік тому

      @@TomDoesTech when i hit the healthcheck route I get an error that says "unable to connect to remote server". but the console shows app is running on the designated port

    • @TomDoesTech
      @TomDoesTech  Рік тому

      @@christopherugochukwu3517 are you using Mongo Atlas or something? What is the "remote server"?

  • @chukaezem6267
    @chukaezem6267 Рік тому +1

    Hey Tom, great tutorial. At 1:32:19 after updating the session to valid: false; shouldn't the get request to fetch all sessions return a 403 unauthorized error, as we just invalidated the current session to be false, and there is a requireUser Middleware on that route, and deserializeUser fetches the accessToken(which is supposed to be invalid now?)

    • @TomDoesTech
      @TomDoesTech  Рік тому

      yeah

    • @chukaezem6267
      @chukaezem6267 Рік тому

      @@TomDoesTech But I doesn't in the video. We are still able to get Sessions. I assume that when we consume the API on the frontend, there'll be a method of invalidating the accessToken to circumvent it.

  • @johnwick97t764
    @johnwick97t764 Рік тому +1

    These contents are way better and productive than other so call "paid courses". Thank you so much for your service

  • @geuxor
    @geuxor 2 роки тому +1

    Thanks for a great lesson! Would be great to see a repo for the same but with sequelize/postgres instead of mongoose :) Do you maybe have anything already?

  • @BarakAlmog
    @BarakAlmog 7 місяців тому +1

    Great tutorial! Thanks so much.

  • @irahazda
    @irahazda Рік тому

    What are we supposed to set as accessTokenPrivateKey, accessTokenPublicKey, refreshTokenPrivateKey and refreshTokenPublicKey in the config/default.ts? I keep getting an error saying Configuration property "mykey" is not defined

  • @5042DaMeatShoww
    @5042DaMeatShoww 2 роки тому

    Am I doing something wrong if my connections connect and after a few disconnect? I'm having an issue with my /healthcheck returning the
    Error
    Cannot GET /healthcheck

  • @okegbemijoshua3342
    @okegbemijoshua3342 2 місяці тому

    hello,
    how do we access res.local.user.sesssion , since our user model does not have the session field

    • @user-oz3hc6lj2e
      @user-oz3hc6lj2e 2 місяці тому

      yeah, it's an error. Look at your mongo db session collect, I think you would probably needed _id

  • @antoniosalzano5253
    @antoniosalzano5253 2 роки тому

    export async function createProductHandler(
    req: Request,
    res: Response)
    {}
    Where can i read more about this filtering the request? I would like to understand more about this?

  • @binitrupakheti4246
    @binitrupakheti4246 3 роки тому +1

    Isn't it better to use something like a .env file for storing configs?

  • @nonybrighto
    @nonybrighto 5 місяців тому

    Migrating from js to typescript for express and I am really glad I found this! Wish I found it a little bit earlier. Would have saved me the stress of digging around for some things I know so far! Thanks a lot! You deserve a cofee!!

  • @adrianogonzalez5269
    @adrianogonzalez5269 3 роки тому +1

    Great video! loved to see a video on Apollo GraphQL

  • @abdallahazme4757
    @abdallahazme4757 6 місяців тому

    What is the point of having access and refresh tokens if you send both to the client? wouldn't be better if you kept the refresh token in the server!

    • @TomDoesTech
      @TomDoesTech  6 місяців тому

      Why would you keep it on the server? The refresh tokens allows the holder to refresh their access token. If the holder is the server, it may as well not exist.

    • @abdallahazme4757
      @abdallahazme4757 6 місяців тому

      the server is more secure for storing refresh tokens. If the access token has expired, I would simply check if there is a refresh token assigned to this user on the server, reissue the access token, and send it back with the response. However, I wouldn't expose the refresh token to the client@@TomDoesTech