Mongoose Validation | Creating a REST API with Node.js

Sdílet
Vložit
  • čas přidán 14. 12. 2017
  • In the last video of this series, we added MongoDB and connected our product routes via Mongoose. Let's now also ensure that only the right data makes it into the database and let's also improve our Http responses.
    ----------
    Learn Node.js in our comprehensive 30h+ course: acad.link/nodejs
    Source Code: github.com/academind/node-res...
    ----------
    • You can follow Max on Twitter (@maxedapps).
    • You can also find us on Facebook.( / academindchannel )
    • Or visit our Website (www.academind.com) and subscribe to our newsletter!
    See you in the videos!

Komentáře • 125

  • @Andrey-il8rh
    @Andrey-il8rh Před 6 lety +128

    Just a small note of improvement: if you want to exclude some property from a response, you can just specify minus in front of it, instead of specifying all properties that you want to keep, so instead of
    select('_id name price')
    you can write
    select('-__v')

    • @academind
      @academind  Před 6 lety +29

      Yep, definitely an useful alternative - thanks for sharing Andrey!

    • @Andrey-il8rh
      @Andrey-il8rh Před 6 lety +5

      You're welcome, Max ;)

    • @tareb_b
      @tareb_b Před 5 lety +3

      We can also write Product.find({},{name:1,price:1}) instead of select method

    • @abdullahalkurdi6845
      @abdullahalkurdi6845 Před 5 lety

      @@tareb_b thats also correct

    • @luckystarsakkeer1312
      @luckystarsakkeer1312 Před 5 lety +2

      @@academind Hi, Max. Can you upload another step by step playlist. How to implement ORM with mySQL into Node Js project. It's my request. :). i'm waiting for your reply, Or refer me some tutorials for this. I'm new to Node Js. I'm working as a Front end developer. Now I started the Back End Development. Your RESTful API tutorial was awesome and very clear. I want to use mysql in my project. Still I couldn't get the perfect tutorial for my problem.

  • @nicot2895
    @nicot2895 Před 6 lety +1

    Great stuff! Really... empowering. Thanks, Max!

  • @pigpig333666999
    @pigpig333666999 Před 6 lety +8

    Your Channel like a master of full-stack developer
    There are many information
    Thanks a lot !

    • @academind
      @academind  Před 6 lety +1

      Happy to read that you like the different topics covered on the channel. Thank you for sharing this!

  • @dj829darwin
    @dj829darwin Před 6 lety

    Thanks for doing this series!

    • @academind
      @academind  Před 6 lety +1

      Always happy to release new videos and even more happy to see that you like it, thanks a lot :)

  • @sigraheiminn
    @sigraheiminn Před 4 lety +1

    Is there an async - await version of the router functions somewhere to be found? Great tutorial by the way!!

  • @nodeShode
    @nodeShode Před 6 lety

    very usful tutorial ...Thanks Max

    • @academind
      @academind  Před 6 lety

      Thank YOU for your comment Rehan, makes me happy to read that you like it!

  • @arkanglegeibriel
    @arkanglegeibriel Před 4 lety +3

    9:21
    possible alternative:
    url: `${req.protocol}://${req.get('host')}${req.originalUrl}/${doc._id}`

  • @dots1p
    @dots1p Před 6 lety +7

    9:28 I find it useful to put api endpoint to .env file.
    So, for anyone following the tutorial, in your .env file add "APP_URL=localhost:3000" and use it in 'api/routes/product.js:21' as `process.env.APP_URL + '/products/' + doc._id`

    • @JLucRob
      @JLucRob Před 6 lety

      That's not working for me. I added "APP_URL":"localhost:3000" to my nodemon.js file, which is located in my root folder alongside app.js.
      I use it like this in my api/routes/product.js file: url: process.env.APP_URL + '/products/' + doc._id
      It shows undefined for process.env.APP_URL
      Do you know how to make it work?

    • @MehmetALTINEL
      @MehmetALTINEL Před 6 lety +1

      for getting request URL
      request:{
      type:''GET',
      url: req.protocol + '://' + req.headers.host + req.url + 'product/' + doc._id;
      }

    • @sujitkumarsingh3200
      @sujitkumarsingh3200 Před 6 lety +1

      If the main domain remains same as the domain for new requst, I usually do following -
      Instead of - "somedomain:portnumber" + "/products/" + result._id;
      Use partial path - "/products/" + result._id;
      Browser will automatically complete this partial path by prepending main domain URL.

    • @MdRashedulIslamS
      @MdRashedulIslamS Před 5 lety

      You can use dynamic like this way url: req.protocol + '://' + req.get('host') +'/products/' + doc._id

  • @muhammadtahir6118
    @muhammadtahir6118 Před 6 lety +2

    Very helpful. Please make videos on graphQL

  • @yaolegoleynik
    @yaolegoleynik Před 5 lety

    Awesome tutorials

  • @kerendn
    @kerendn Před 5 lety +2

    Excellent tutorial! Learning a lot in a short time and easy to follow along.
    Just a minor note about port 9:45 - if the port number was set in the env, your links would be wrong since you hard-coded port 3000.

  • @aomo5293
    @aomo5293 Před 6 lety

    Thank Thank you very much, That is so Good, Thank a lot,
    44, Agadir, Morocco.

    • @academind
      @academind  Před 6 lety

      Thank YOU so much Agadir, great to hear you're liking it!

  • @ccuenca24
    @ccuenca24 Před 6 lety

    Hi Max! excellent work as usual! thanks a lot, a question, what about swagger docs to go on top down approach, it's posible with node?

    • @academind
      @academind  Před 6 lety +1

      You mean use Swagger to create the Node/Express API? That is possible, yes - the following article might provide a good start: scotch.io/tutorials/speed-up-your-restful-api-development-in-node-js-with-swagger

    • @ccuenca24
      @ccuenca24 Před 6 lety

      Academind thanks!!!

  • @AbhishekKumar-mq1tt
    @AbhishekKumar-mq1tt Před 6 lety

    Thank u for this awesome video

    • @academind
      @academind  Před 6 lety

      Thank YOU for your comment Abhishek, happy to read that you like it :)

  • @MdRashedulIslamS
    @MdRashedulIslamS Před 5 lety

    Guys, use dynamic url: req.protocol + '://' + req.get('host') +'/products/' + doc._id

  • @alihasana2009
    @alihasana2009 Před 6 lety

    There is one more alternative
    Inspite of write the code in every request, we set the mongoose model in prodect.js as below, as using the lodash pick module from npm
    import pick from 'lodash/pick'
    ProductSchema.methods.toJSON = function () {
    let productObject = this.toObject()
    return pick(productObject, ['_id', 'email'])
    }

  • @phamnhans
    @phamnhans Před 4 lety

    thank sir!

  • @brianwahome5789
    @brianwahome5789 Před 5 lety

    When creating products, change the request type from GET to POST in the request object: 11:47

    • @AHeaney
      @AHeaney Před 4 lety

      It should still be GET because you're not making a POST request to that url. You are making a GET request to view the created product.

  • @fredhair
    @fredhair Před 4 lety +1

    I changed the patch so that I can just pass in an object with key value pairs of what I want to modify and then the new value e.g. "name": "new prod name". On the server side I check that the model schema has the key (except for __v & _id) and if so updates it, this way I can update many fields easily with the same structure as a post request.

  • @ahronlu1
    @ahronlu1 Před 4 lety

    Hi Max,
    first of all thanks for the amazing series..
    i dont know why but since i added
    const productSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: { type: String, required: true },
    price: { type: Number, required: true }
    });
    to this
    const productSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: String,
    price: Number
    });
    i cannot post new products anymore

  • @DevangPatil
    @DevangPatil Před 5 lety

    Awesome..

  • @mooodddy1
    @mooodddy1 Před 6 lety +13

    plz Make Video about authentication + Facebook authentication + ACL in REST API with Node.js
    REPLY

  • @shakeelshakeelahmad8793

    i have a trouble in get request ,when i get it from postman it is not respond

  • @marcin2x4
    @marcin2x4 Před 3 lety

    How to get message attribute at 1:53? I get error as in the example but not all attributes are displayed.

  • @EduardoBeecheO
    @EduardoBeecheO Před 6 lety +2

    Thank you very much Max, I have been following this set of tutorials since you published them and I am very grateful for all the time and effort you have invested in them. Keep up the good work!. Greetings from Costa Rica.
    Oh, one request (if possible) can you create an API route where we can insert a new record but only using GET, no POST. Something like myServer/products/insert/theName/thePrice
    That would be just great!

    • @academind
      @academind  Před 6 lety

      Thanks for your great feedback!
      But inserting via GET? Sounds a bit wrong to me to be honest...

    • @EduardoBeecheO
      @EduardoBeecheO Před 6 lety

      Hehehe, ok, let me elaborate. I'm into IoT and a a lot of the sensors we use have very low resources (computing power, memory, etc) so we don't have many luxuries, one of them is wasting memory building a full http request (headers, body, etc). In these cases the easy, and cheapest way in terms of resources, to do it is just build a url and 'GET' it.
      A very good example of what I'm saying can be found here: phant.io/docs/input/http/ please take a look at it, and you'll see what I'm talking about.
      Actually they work with a url like this one:
      'GET' myServer/insert/pubKEY?FIELD1=VALUE1&FIELD2=VALUE2

    • @luckystarsakkeer1312
      @luckystarsakkeer1312 Před 5 lety

      @@academind Hi, Max. Can you upload another step by step playlist. How to implement ORM with mySQL into Node Js project. It's my request. :). i'm waiting for your reply, Or refer me some tutorials for this. I'm new to Node Js. I'm working as a Front end developer. Now I started the Back End Development. Your RESTful API tutorial was awesome and very clear. I want to use mysql in my project. Still I couldn't get the perfect tutorial for my problem.

    • @roygates6328
      @roygates6328 Před 4 lety

      @@luckystarsakkeer1312 check out: "npm node-mssql" you will find it useful

  • @arvi8843
    @arvi8843 Před 6 lety

    Is there a reason why you use node's default promise over bluebird's promise? Or was it just an example? Thanks a lot. :)

    • @academind
      @academind  Před 6 lety +1

      I'm pretty happy with the default one, that's why I normally use it

  • @someone11233
    @someone11233 Před 3 lety

    Plz make a video on mongoose discrimators

  • @Kohrath
    @Kohrath Před 6 lety +2

    I never used MongoDB and Mongoose but is there any risk of database manipulation (script injection, etc.)? if the user pass a string that's actually a script or something?

    • @academind
      @academind  Před 6 lety +2

      MongoDB indeed also can be vulnerable to injection attacks, yes. Not by passing a normal JS script in there but by manipulating queries. See this article: blog.sqreen.io/mongodb-will-not-prevent-nosql-injections-in-your-node-js-app/

    • @Kohrath
      @Kohrath Před 6 lety +1

      Academind I know I should wait and see but are you planning a episode that show a easy and efficient way to prevent those attacks? Thank you for the great video !

  • @justinreyesv
    @justinreyesv Před 5 lety

    man youre the best

    • @academind
      @academind  Před 5 lety

      YOU are the best, thanks so much for your awesome feedback!

  • @davidwelsh8387
    @davidwelsh8387 Před 4 lety

    The .catch statement is giving me 7 errors in the code, anyone else getting that?

  • @daniilvatahovych491
    @daniilvatahovych491 Před 6 lety +1

    Hi Max!
    First I want to say thank you very much for your courses and tutorials.
    Secondly, can I ask you to use ES6 + in writing code? As this will give an opportunity to feel all its possibilities on real examples.
    Thank you.

  • @MultiTechguy101
    @MultiTechguy101 Před 6 lety

    Y does the save for post not have a .exec() chained on?

    • @psionicronin1911
      @psionicronin1911 Před 5 lety +1

      .save() already returns a promise.
      The other functions don't. So we used .exec() to turn them into a promise so we can use .then() & .catch() which are exclusive to Promises.

  • @nodeShode
    @nodeShode Před 6 lety

    at 7:23 need not to use .select('name _id price)
    when u are returning response object in res.status(200).json(response)

  • @jumbo999614
    @jumbo999614 Před 3 lety

    7:23. It will be better if comma is allowed to separate each item.

  • @ZenOfTube
    @ZenOfTube Před 3 lety

    This has been a great tutorial! I am experiencing a problem though when trying to use process.env in our product.js file; if I add this to my nodemon.json file:
    "SERVICE_URL": "localhost:3000"
    and try to use it in my request url like this:
    url: process.env.SERVICE_URL + '/products/' + doc._id
    the first part of the url is undefined. Can anyone tell me how to get the url (our "domain") from my nodemon.js file into my product.js file? It does not work the same way it does in app.js for the MongoDB password.

  • @user-rp6ze2mv2l
    @user-rp6ze2mv2l Před 2 měsíci

    why when i try to GET requests it's "sending request..." forever

  • @confearsion3778
    @confearsion3778 Před 4 lety +1

    9:50 Somebody please tell me how can I add multiple requests , like for updating and deleting

  • @dipakprajapati6855
    @dipakprajapati6855 Před 6 lety

    please one playlist for express framework in detailed.

    • @academind
      @academind  Před 6 lety

      Thanks for the suggestion. I'll see if I can add some general content on it in the future

    • @dipakprajapati6855
      @dipakprajapati6855 Před 6 lety

      thank you.

  • @TheSldsnake
    @TheSldsnake Před 6 lety +6

    plz node course !!

    • @khorotyanvahagn
      @khorotyanvahagn Před 6 lety +3

      Yeah, I would love to see a Node course hopefully it will include intermediate to advanced material. Again, whatever he makes, it will be the best Node course in Udemy like his other courses :D

    • @academind
      @academind  Před 6 lety +8

      Thank you so much guys - that truly means a lot to me! We'll see. A node course is not planned right now but certainly something I'm evaluating :)

    • @gabrieljoshuapaet2572
      @gabrieljoshuapaet2572 Před 6 lety

      I would love to see a node course too!

    • @elvestrindade7047
      @elvestrindade7047 Před 6 lety

      your courses are awesome, make node+mongodb course together

    • @yuliankarapetkov
      @yuliankarapetkov Před 6 lety

      Isn't this the Node course? czcams.com/video/65a5QQ3ZR2g/video.html

  • @priyajain6791
    @priyajain6791 Před 6 lety +1

    Getting error for PATCH request. All I could get is the message : "req.body is not iterable" again and again whenever trying to send the request using postman. Please help fix it.

    • @gofudgeyourselves9024
      @gofudgeyourselves9024 Před 5 lety

      I am also getting this error. Have you found a solution?

    • @keithin8a
      @keithin8a Před 5 lety

      are you sending your request body as an [ ]? He explained last video that because you are iterating over the patch message you need to send it as an array. He briefly mentions it in this video too, but its easy to miss.

    • @rossi4303
      @rossi4303 Před 5 lety

      I also had this error.
      I fixed it by setting the send-type of the message to JSON (application/json).
      In postman on the row where you can choose between raw, none, form-data,... on the right side there is a dropdown menue. There you have to set it to JSON. In my case it was set to Text. I don't know why.

  • @peoray
    @peoray Před 5 lety

    Max, you mentioned the use of spread operator at 8:32 but you didn't show us the code. Could you please do this so we can learn it. If anyone can help, please do.

  • @darshu62
    @darshu62 Před 6 lety

    Hi,
    Could you please tell me how to give unique project name. for example:
    Project name (unique) *
    ProjectId(auto indexed)
    Project Description: (string)
    Events [ "ids"] (array)
    Dimensions[]()
    Customers[] i need schema to this. could you please help me? and also how to use enums in nodejs?
    i need to create a drop down menu .
    for example. Events enum[type: raw, enirched]

    • @md.aminmithun534
      @md.aminmithun534 Před 5 lety

      hello, write Project_name: {
      type: String,
      unique: true,
      required: true
      }

  • @danielchen6688
    @danielchen6688 Před 5 lety

    Can you tell me how to crypt "MONGO_ATLAS_PW" to "CTdYB4jqX6uovW7O"? thanks

  • @mmk1334
    @mmk1334 Před 3 lety

    More love from afghanistan

  • @murtujakavantwala5135
    @murtujakavantwala5135 Před 4 lety

    Special message to everyOne who is using mongoose
    please select the node version 2 for the string , only then you can connect o your database

  • @aliazlanaziz
    @aliazlanaziz Před 4 lety

    I m receiving these errors plz someone help me i searched on the whole net could not find the solution for this one
    (node:2524) UnhandledPromiseRejectionWarning: TypeError: res.status(...).json(...).catch is not a function
    at C:\Users\OK Computers\Desktop\Web Dev\Acadmia\api
    outes\products.js:57:11
    at processTicksAndRejections (internal/process/task_queues.js:85:5)
    (node:2524) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

    • @nojomyth
      @nojomyth Před 3 lety

      10 months too late
      You don't call the catch on the json() but on the exec() function xD

  • @yogyatanilkanth1529
    @yogyatanilkanth1529 Před 8 měsíci

    For patch I am continuesly getting below error:
    {
    "error": {
    "message": "Product.update is not a function"
    }
    }
    my string is below:
    [
    { "propName": "name", "value": "New Product"}
    ]
    Please someone help me to know issue

    • @RABWA333
      @RABWA333 Před 7 měsíci

      Post your code handler (router) sobI can help

    • @averagestudent9070
      @averagestudent9070 Před 6 měsíci

      Product.update method is deprecated, use Product.updateOne()

  • @radosawguchowski1206
    @radosawguchowski1206 Před 4 lety +1

    Hi 22.10.2019 - i got err req.body is not iterable, when we want to patch product changes to fix it
    use instead
    for (const [key, value] of Object.entries(req.body)) {
    updateOps[key] = value
    }
    and later on using update we got some warning, we should use (in this case ) updateMany
    link: mongoosejs.com/docs/deprecations.html

    • @conaxliu9677
      @conaxliu9677 Před 4 lety

      If you got the error in Postman, that would be because in the body section you had selected "raw Text" instead of "raw JSON", as happened to me.

    • @jennyzhang5481
      @jennyzhang5481 Před 3 lety

      @@conaxliu9677 how can I use with x-www-urlenoded

    • @conaxliu9677
      @conaxliu9677 Před 3 lety

      @@jennyzhang5481 Maybe you mean application/x-www-form-urlencoded? developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

  • @arminzohrabi1692
    @arminzohrabi1692 Před 6 lety

    If you don't need version_key(__v), you can just:
    createdProduct: {
    ...result.toObject({ versionKey: false }),
    request: {
    type: "POST",
    url: "/products/" + result._id
    }
    }
    or
    new Schema({..}, { versionKey: '_somethingElse' })

  • @tareb_b
    @tareb_b Před 5 lety

    P.S. We don't need 'mongoose.Promise = global.Promise' after Mongoose 5.0 version

  • @user-gk3pu2db7i
    @user-gk3pu2db7i Před 6 lety

    Koennten Sie ein Full-Stack Kurs( Node.js ) im Udemy.com anbieten?

    • @academind
      @academind  Před 6 lety

      Danke für den Vorschlag! Das ist etwas, worüber ich nachdenke aber ich habe mich noch nicht entschieden um ehrlich zu sein

  • @pablovent8622
    @pablovent8622 Před 6 lety

    Max I'm creating products just fine, but when I click the link thereof and hit send GET request, I'm getting an error:
    {
    "error": {
    "message": "Not found"
    }
    }
    Any idea what's going on? I have checked carefully my code but I don't see any syntax errors or otherwise for that matter? Is there a github for this tutorial I can compare my code with?
    Just created a new product and it works. I'll create another one and see how it goes.

    • @pablovent8622
      @pablovent8622 Před 6 lety

      The GET routes are working. It's postman who's giving me grief. When after creating the product, I click on the url which takes me to another tab, a GET one, the api fails to find the product on hitting send. If, on the other hand, I manually GET the recently created product by copying and pasting the _id at the end of the url, I don't get the error but the product instead. I'll plod on and see if I can find the bug...

    • @pablovent8622
      @pablovent8622 Před 6 lety +1

      Fixed!!!!

  • @yvhnn
    @yvhnn Před 5 lety

    Sorry, but I don't get why we add this for the response of product(s)
    What is there a point of having it in there?
    request: {
    type: 'GET',
    url: 'localhost:3000/products/' + product._id
    }

    • @harievenad4189
      @harievenad4189 Před 4 lety

      Thats just the additional information for someone who needs, if you don't need you can simply ignore

  • @conaxliu9677
    @conaxliu9677 Před 4 lety

    12:51 One thing I really don't get...if I do res.status(200).json(doc) then I get this response:
    {
    "_id": "5e320718d4e92a3198fa7706",
    "name": "Superman IV",
    "price": 29.99
    }
    However, if I do res.status(200).json({
    ...doc,
    message: "Test message"
    })
    I expect the response to be:
    {
    "_id": "5e320718d4e92a3198fa7706",
    "name": "Superman IV",
    "price": 29.99
    ,
    "message": "Test message"
    }
    but instead I get this:
    {
    "$__": {
    "strictMode": true,
    "selected": {
    "name": 1,
    "price": 1,
    "_id": 1
    },
    "getters": {},
    "_id": "5e320718d4e92a3198fa7706",
    "wasPopulated": false,
    "activePaths": {
    "paths": {
    "price": "init",
    "name": "init",
    "_id": "init"
    },
    "states": {
    "ignore": {},
    "default": {},
    "init": {
    "_id": true,
    "name": true,
    "price": true
    },
    "modify": {},
    "require": {}
    },
    "stateNames": [
    "require",
    "modify",
    "init",
    "default",
    "ignore"
    ]
    },
    "pathsToScopes": {},
    "cachedRequired": {},
    "$setCalled": {},
    "emitter": {
    "_events": {},
    "_eventsCount": 0,
    "_maxListeners": 0
    },
    "$options": {
    "skipId": true,
    "isNew": false,
    "willInit": true
    }
    },
    "isNew": false,
    "_doc": {
    "_id": "5e320718d4e92a3198fa7706",
    "name": "Superman IV",
    "price": 29.99
    },
    "$locals": {},
    "$init": true,
    "message": "Test message"
    }
    To get the expected response I then need to do:
    res.status(200).json({
    ...doc._doc,
    message: "Test message"
    });
    Why oh why???

  • @RockCYP
    @RockCYP Před 6 lety +3

    Sad to say but 3/4 of the video where not mongoose validation but populating responses.

    • @SaladoElFede
      @SaladoElFede Před 6 lety +3

      Still useful.

    • @academind
      @academind  Před 6 lety +3

      Sorry to hear that the title was a bit deceiving. Couldn't decide for that video ;)

  • @MehmetALTINEL
    @MehmetALTINEL Před 6 lety

    for getting request URL
    request:{
    type:''GET',
    url: req.protocol + '://' + req.headers.host + req.url + 'product/' + doc._id;
    }

  • @hamzarasool7669
    @hamzarasool7669 Před 2 lety

    This Tutorial is too OLD now they need to update it at least, or make new

  • @mohammadyounoch5952
    @mohammadyounoch5952 Před 2 lety

    (node:12416) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: mongoosejs.com/docs/promises.html
    have any solution for warning message