Check out a free preview of the full API Design in Node.js (using Express & Mongo) course:
The "Schemas" Lesson is part of the full, API Design in Node.js (using Express & Mongo) course featured in this preview video. Here's what you'd learn in this lesson:

Mongoose schemas can be used to add structure and validation through a process called data modeling. Scott walks through the code to create a schema and demonstrates the different ways properties can be defined.

Get Unlimited Access Now

Transcript from the "Schemas" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Speaker 1: So, data modelling. Now that we have our scaffold built out, we build out the routes, we have the router working, we got our config set up. We have some utilities with middleware, the server is running. Everything's good. Now we need to plug in some actual data and the controller to that data.

[00:00:19] Remember in the last step we set all that stuff up?
>> Speaker 1: So now we just need to replace the stuff that we have in here. So if we go look in here, right we're doing nothing but sending it back to okay. We need to add in some models and some controllers in here.

[00:00:35] So the first thing we need to do is before we do this, we need to figure out how our data is gonna look like. But before we do that, we need to figure out how to even model the idea. So we can use schemas in Mongoose to add structure and validations to our data.

[00:00:47] So Mongo does not need schemas, though. Remember, again, Mongo, the database itself, doesn't need schemas, we can just throw whatever we want at it. Mongoose gives us the ability to define those schemas and those blueprints to rationalize about our data and have certain guarantees and validations and lifecycle checks, and stuff like that.

[00:01:05] That's Mongoose. It's not Mongo.
>> Speaker 1: We also need some sort of relationships with our data. So for instance, users can create posts, and posts have categories. Right, so if a user can create posts, that's a one to many relationship. One user can have many blog posts. Right, but a blog post only belongs to one user and a blog post can have many categories, right, and a category can belong to many posts.

[00:01:35] So that's a many to many relationship. So if you've ever dealt with databases in SQL, then you kind of know what I'm talking about. If not, it's not that important, this is not a database class, this is not a class on Mongo, it's a class on building a API.

[00:01:48] And this is just a small part. So, you can use whatever database you want. I just want you to know that's how you should think about the data. That's how we're gonna think about it.
>> Speaker 1: So, Mongoose makes that, the setting of the relations is actually pretty easy.

[00:02:04] If you've ever dealt with a relational database then eventually it's like whatever, it's cool, you normalize it then eventually probably denormalize it later on. But, which, you probably break stuff, but what happens is Mongoose actually makes it easy. There's no join tables, none of that stuff like that, it's just references.

[00:02:20] So here's an example of modeling a todo resource. Comment, so require Mongoose, the first thing we do is we make an schema. And the way we do that is we can just call new mongoose.Schema with a capital S. That's a function that takes on an object. This object is our blueprint.

[00:02:40] So whatever properties we've thrown this object, those are the properties we're saying that we can use that's that whatever property is pulling this object, it's the same thing we were saying.
>> Speaker 1: Up here. This is us modeling our data up here. These are the properties that can exist.

[00:02:56] That's what we're doing down here.
>> Speaker 1: So that means we want a completed property on this resource and its value type is a boolean.
>> Speaker 1: All right, so it's either true or false. And that's not something, all right, if you know JavaScript, boolean is not something that, that's not something Mongoose or Mongo gave us, it's just a boolean.

[00:03:23] Everything in JavaScript's an object, a boolean is no different. So that's the boolean. We can also add validations, there should be a comma right here by the way, but we can also add validations to an object or to a property. And the way we would do that is if you wanted to just add more than just what type the property is, you have to use object literal as the value, and then you can add more properties on it.

[00:03:49] So, we also went a content property on a to do. So, a to do says whether it's completed or not, true or false and then an actual content of to do of the message or whatever. It's type is string, so that's exactly like saying completed boolean. When you put an object right here and you say type: string it's the same thing, but we don't have to put type boolean up here cuz that's the only thing we're doing.

[00:04:11] We're not doing anything else with this property right here. So we can just say boolean. But we wanted to do something else with this property down here, so we have to make this object literal. We had to say hey, you're type is gonna be string. And then the validation that we wanted was it has to be required.

[00:04:26] So we put required true that means you can not save a new document a new to do without specifying this and it has to be tied to the string. So if you don't pass in a string to the property content as your trying to create a new one Mongo, or Mongoose would throw an error.

[00:04:46]
>> Speaker 1: It will throw a validation error. And it will tell you where too, it will point right to it.
>> Speaker 2: They're asking if there is a date type?
>> Speaker 1: Yeah, we're gonna get to all the types right below this. Yes, there is a date type.
>> Speaker 1: So, the next thing we need to do is kind of what I talked about in the last step is we made a new schema, now we need to register the schema with Mongoose, so I can tell Mongo about it.

[00:05:14] And the only way we do that is we use the mongoose.model method, which I told you is a getter and a setter. The first argument is the name of the collection that we want to make, and the second one is the blueprint for that, the schema object. So remember, it's going to be lowercase and pluralized.

[00:05:29] It doesn't matter what you put here, lowercase and pluralized. And then the actual thing that it returns is the actual model that we'll be using inside of our API. So when want to query the todo model, we'll be using this thing right here that got returned. So it makes sense to export it because we'll be requiring it everywhere else.

[00:05:56]
>> Speaker 1: So usually you'll see a pattern where this thing's just module.exports=mongoose.model. It'll just skip this line right here, I just did it on two lines so it's easy to read.
>> Speaker 1: Any questions on that?
>> Speaker 1: That's like a basic blueprint. This is valid, except for this comma missing here.