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