Eve: Building RESTful APIs with MongoDB and Flask Transcripts
Chapter: Schema definitions and validation
Lecture: Built-in validation rules

Login or purchase this course to watch this video and the rest of the course contents.
0:00 All right, as you can see, while you weren't watching, I went back to our basic app and expanded the schema definition a little bit.
0:08 I added new rules for the fields we already know, and also added new fields like born, age, role etc. First name is still a string,
0:17 but now it has min and max length rules, which, of course, means that when a value comes in with this field, it must be between 1 and 30 in length.
0:28 Last name is more interesting, again, it's still a string, but now we also have a max length and the field is also required and must be unique.
0:39 Now by default, fields are not required. So first name here you don't have to provide it with every single document.
0:47 If you don't have a first name with your document, it's fine, the document will be saved anyway,
0:52 but last name you have to provide it because it is required. And not only that, it is also unique, which means that the value coming with the document
1:02 must be the only one in the endpoint for this field. So if we already have a John Doe and we try to save a Mike Doe,
1:12 we get an error because the value for last name is not unique. So pretty powerful, it works really well with Mongo.
1:18 There is one small caveat you want to know about and that is that if you have bulk inserts enabled at your endpoint,
1:26 because the unique rule is only checked against the document already stored on the data set.
1:32 If you have five documents coming into your system with the same request and they have duplicated value for the last name,
1:40 as long as this last name does not exist in the database, they will be accepted. If this is a risk you don't want to run
1:48 you might disable bulk inserts for the endpoint, so the clients are forced only save one document at a time,
1:55 or you might want to build a custom validator which will also check the values within the document.
2:01 Next, we have the born field which is new, and it is of type datetime. Speaking of types, we only saw the string and now the datetime type
2:10 If we go to the documentation site, we see that we have a number of options there Of course, the basic ones like boolean, integer, float, number
2:20 which is basically integer and float values allowed, datetime, dictionaries, lists, media, which is very interesting,
2:28 it allows us to store images, pictures and movies, and if we're using the Mongo data layer which is the default,
2:36 the one we're using in this course, we also have the Mongo types like object id, db reference, and all the GeoJson types
2:45 like point, multi point, etc, and also the decimal tag type which only recently has been added to the Mongo features set.
2:57 Age is read only, which means that clients can't write or overwrite it. So documents coming into the API cannot have the age field
3:07 otherwise they will be rejected. So why would you want to add this field to the schema?
3:13 Well, the reason is that by default, Eve will only return fields it knows about. So you still want to add age if you want
3:21 this field to be returned from the database to your clients. Next up is role, role is a list, and it comes with two new rules,
3:30 one is allowed, which supports a list of allowed values for the field and the second one is very interesting, and it is default
3:38 which means that whenever a document comes in with no value for this field, a default will be set by the framework and stored with the document.
3:46 So in this case, every time a document with no role comes in, a default role of author will be set for this field.
3:55 The last field I added to the schema definition for the people endpoint is location. As you can see, this is of type dict
4:03 and because it is a dictionary, we can define a schema for the dictionary itself. In Mongo DB terms, this is going to be a subdocument
4:10 and when we define a sub document, we can also define its schema, so again, all the validation rules we've been setting for the main document
4:18 can also be set for the subdocument. Here we only have two fields for the location which are address and city.
4:27 City is a string as address, but it is also required. Now, because location itself is not required.
4:35 We aren't requested to provide this feed with every document, but if we provide field, then the city field is required and should be added,
4:45 otherwise, the document will be rejected. If we wanted a location to be required, we need to do this, so in this case location is required,
5:01 and when we provide it, we also have to provide city while we can avoid providing address.
5:08 All right, I already saved these new settings and also relaunched let me know about the postman and try to make a post of a new document
5:19 like the ones we have been storing so far. So only a first name field set to Bill. If we send this request over, what we get back is
5:30 as expected, an unprocessable entity error, with two issues, one for the location field
5:37 which is missing and it is required, and the same for last name, both of them are indeed required as per our settings.
5:45 So, let's go back to our request and add values, let's pretend I forget to add the city
6:02 okay, let's try to send these over, new errors, as you can see, last name now, we provided the last name value
6:12 but it is not unique because on the people endpoint we already have a John Doe so since last name is unique, this value is not accepted,
6:21 and then the location, we provided that location field but the city field within the location subdocument is still missing, so let's fix this.
6:39 All right, now we should be good to go, let's try that, great, so this time we get a created status code,
6:48 we can go and do a get request to our document endpoint we get the unique id of the document and hit the endpoint there,
7:00 and yes, we have the unique id of course, first name, last name, location
7:06 as we provided it, but we also have a role field with the default value of author. Of course, the age field is still missing
7:17 it was read only so we didn't provide it, but there is no age field in the document on the data set,
7:23 so it is not being returned by the API, but that's fine.

Talk Python's Mastodon Michael Kennedy's Mastodon