Eve: Building RESTful APIs with MongoDB and Flask Transcripts
Chapter: Schema definitions and validation
Lecture: Advanced validation rules
0:01 I want to show you a few more rules, and the first one is going to be coerce. With coerce, you can pass a callable, and a callable will be applied
0:10 to the value coming into the field, and the return value of your callable will be used to update the field
0:18 before validation is performed on the document. So, here I updated my age field, it isn't a read-only field anymore, now it is a writable integer,
0:28 but we're also applying a coerce rule and the callable we choose to use here is int,
0:36 so we're converting the value of the field to an integer, if it isn't already. Let's see this one in action.
0:43 So we have this person here, Mr. Roger Federer, he lives in New York, and he is very young, he has an age of 18,
0:52 but as you can see, I am passing a string here while age is supposed to be an integer. So normally, we will get an error when we try to save this guy
1:02 because the type is not the correct one, the expected one, but let's see what happens when we post Roger Federer to our API.
1:12 As you can see, we get a created, no errors, and we inspect the values of this document, we see that the first name, last name, location and age
1:23 have been converted to an integer for us. And also you can use an iterable here in your coerce rule, if you do that, any function you provide
1:36 within your iterable will be applied in sequence. So in this case, first we will get an integer conversion applied to the value,
1:44 then the result, the return value of this conversion will be passed to the next function, which in this case is a string conversion
1:53 it doesn't make any sense, it is going to get an error to us, let's go back to hit this error again, but you get the point.
2:00 Another powerful rule I want to show you is regex, what it does is pretty obvious I think, it allows you to the final regular expression
2:11 and the value coming into the field will be matched against the expression and only if it passes validation against the expression, it will be accepted
2:21 so let's go back to Postman, I have my email field here and I am passing a string, it is a valid string but not a valid email.
2:31 If I try to send this person to the API I get an error, email does not match the regular expression. Now if I go and fix my expression,
2:43 I should get a green light, exactly, so now I have my email validated, correctly, as expected. Another use for rule is dependencies.
2:56 This is very common here I have one field which is dependent on others So here I added a middle name field and it depends on first name and last name
3:06 which means that the field itself is not required. In fact, there is no required rule, but if you provide a middle name,
3:14 you also must provide the first name and last time, otherwise, the field would be rejected. You can also have only one dependency of course,
3:22 in this case, you can just pass a string with the field name without the need of full list.
3:28 So let's, try this one, super simple, we have Scott Fitzgerald, we try to send this one off and we get an error
3:37 because there is an error in the Json, yes, we're missing a comma here, let's try again.
3:44 As you can see me, middle name field, the first name is required if we add the first name which is the second required field
3:53 for middle name to be accepted, we get the created message. So dependencies, you can have more than one field
4:04 if you have more than one you need a list, otherwise the string and another nice feature is that .notation is supported,
4:11 so suppose that you want middle name to be dependent on location.address for example, which means that not only first name and last name,
4:22 but also location which as you might remember is a sub document.address must be present in order for middle name to be accepted.
4:35 Another set of rules I want you to know about is what we call the *of rules. This is a family of rules, actually, you have different variations,
4:46 so you have all of, any of, non of, one of and what these rules do is they allow you to list multiple sets of rules to validate against.
4:59 Let's see an example, here I have a property which is called prop 1 and the type is number, so both integer and floats will be accepted
5:12 but I want to accept numbers which are in a range between 0 and 10 or in a range between 100 and 110. I don't want to accept 50 for example,
5:24 which isn't included in any of these two ranges. So what I am going to use is any of so at least one rule in this iterable must be valid
5:33 in order for the value in this field to be accepted. The rules, as you can see, are defined as dictionaries,
5:39 here is the first rule and then we have the second rule. Let's go to Postman and try this out, prop 1 is 50,
5:50 as you can see for field prop 1 we have an issue and the issue is that no definitions were validated.
5:58 The first one is not valid because the max value is 10 while we provided 50 the second rule is not met because the minimum value is 100
6:08 and again, we provided 50. So depending on your necessity, you can pick the most appropriate of these rules,
6:17 for example, if you don't want any of the schemas to be valid, then you can use none of, and another interesting one is one of
6:29 which validates if exactly one of the provided constraints applies. Another interesting feature of these rules is
6:39 that they allow you what we call a type saver. So, for example, here we are defining a foo field
6:48 which has a rule anyof_type and then we pass a list of types so string and integer, this is equivalent to
6:58 doing foo anyof_type string as a first constraint and type it as a second constraint so let's go back to our number definition here.
7:12 I could replace this with anyof_type integer string, it doesn't really make a lot of sense because we already have the number shortcut for doing this,
7:32 but it is useful to know that you can do this kind of stuff because it allows you to shorthand most of the rules
7:39 And when you have a lot of rules in your schema, it can come in handy.