Mongoose Validation | Creating a REST API with Node.js
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!
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')
Yep, definitely an useful alternative - thanks for sharing Andrey!
You're welcome, Max ;)
We can also write Product.find({},{name:1,price:1}) instead of select method
@@tareb_b thats also correct
@@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.
Great stuff! Really... empowering. Thanks, Max!
Thanks so much Nico!
Your Channel like a master of full-stack developer
There are many information
Thanks a lot !
Happy to read that you like the different topics covered on the channel. Thank you for sharing this!
Thanks for doing this series!
Always happy to release new videos and even more happy to see that you like it, thanks a lot :)
Is there an async - await version of the router functions somewhere to be found? Great tutorial by the way!!
very usful tutorial ...Thanks Max
Thank YOU for your comment Rehan, makes me happy to read that you like it!
9:21
possible alternative:
url: `${req.protocol}://${req.get('host')}${req.originalUrl}/${doc._id}`
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`
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?
for getting request URL
request:{
type:''GET',
url: req.protocol + '://' + req.headers.host + req.url + 'product/' + doc._id;
}
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.
You can use dynamic like this way url: req.protocol + '://' + req.get('host') +'/products/' + doc._id
Very helpful. Please make videos on graphQL
Awesome tutorials
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.
Thank Thank you very much, That is so Good, Thank a lot,
44, Agadir, Morocco.
Thank YOU so much Agadir, great to hear you're liking it!
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?
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
Academind thanks!!!
Thank u for this awesome video
Thank YOU for your comment Abhishek, happy to read that you like it :)
Guys, use dynamic url: req.protocol + '://' + req.get('host') +'/products/' + doc._id
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'])
}
thank sir!
When creating products, change the request type from GET to POST in the request object: 11:47
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.
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.
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
Try drop your old database
Awesome..
plz Make Video about authentication + Facebook authentication + ACL in REST API with Node.js
REPLY
i have a trouble in get request ,when i get it from postman it is not respond
How to get message attribute at 1:53? I get error as in the example but not all attributes are displayed.
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!
Thanks for your great feedback!
But inserting via GET? Sounds a bit wrong to me to be honest...
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
@@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.
@@luckystarsakkeer1312 check out: "npm node-mssql" you will find it useful
Is there a reason why you use node's default promise over bluebird's promise? Or was it just an example? Thanks a lot. :)
I'm pretty happy with the default one, that's why I normally use it
Plz make a video on mongoose discrimators
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?
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/
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 !
man youre the best
YOU are the best, thanks so much for your awesome feedback!
The .catch statement is giving me 7 errors in the code, anyone else getting that?
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.
Y does the save for post not have a .exec() chained on?
.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.
at 7:23 need not to use .select('name _id price)
when u are returning response object in res.status(200).json(response)
in my case, i still get the __v
7:23. It will be better if comma is allowed to separate each item.
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.
why when i try to GET requests it's "sending request..." forever
9:50 Somebody please tell me how can I add multiple requests , like for updating and deleting
Sorry for the stupid question
please one playlist for express framework in detailed.
Thanks for the suggestion. I'll see if I can add some general content on it in the future
thank you.
plz node course !!
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
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 :)
I would love to see a node course too!
your courses are awesome, make node+mongodb course together
Isn't this the Node course? czcams.com/video/65a5QQ3ZR2g/video.html
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.
I am also getting this error. Have you found a solution?
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.
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.
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.
...doc._doc, request: {etc}
@Jack Rong if you have the time please show us , oh wise one
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]
hello, write Project_name: {
type: String,
unique: true,
required: true
}
Can you tell me how to crypt "MONGO_ATLAS_PW" to "CTdYB4jqX6uovW7O"? thanks
More love from afghanistan
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
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)
10 months too late
You don't call the catch on the json() but on the exec() function xD
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
Post your code handler (router) sobI can help
Product.update method is deprecated, use Product.updateOne()
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
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.
@@conaxliu9677 how can I use with x-www-urlenoded
@@jennyzhang5481 Maybe you mean application/x-www-form-urlencoded? developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
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' })
simpler solution is result.select('-__v')
P.S. We don't need 'mongoose.Promise = global.Promise' after Mongoose 5.0 version
Koennten Sie ein Full-Stack Kurs( Node.js ) im Udemy.com anbieten?
Danke für den Vorschlag! Das ist etwas, worüber ich nachdenke aber ich habe mich noch nicht entschieden um ehrlich zu sein
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.
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...
Fixed!!!!
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
}
Thats just the additional information for someone who needs, if you don't need you can simply ignore
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???
Sad to say but 3/4 of the video where not mongoose validation but populating responses.
Still useful.
Sorry to hear that the title was a bit deceiving. Couldn't decide for that video ;)
for getting request URL
request:{
type:''GET',
url: req.protocol + '://' + req.headers.host + req.url + 'product/' + doc._id;
}
This Tutorial is too OLD now they need to update it at least, or make new
(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