Eve: Building RESTful APIs with MongoDB and Flask Transcripts
Chapter: Schema definitions and validation
Lecture: Custom rules and types
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
We already learned that Eve offers a wide and flexible range
0:04
of validation and transformation rules.
0:06
No matter how powerful and rich a validation system is,
0:09
there will always come a moment when you need to go beyond that.
0:14
This is the case when you want to validate a value
0:18
that must conform to standards and conventions,
0:21
which are specific to a certain application field.
0:25
Eve allows to extend the validation system by creating custom rules,
0:30
adding in new types or using validating functions.
0:34
In this lecture, we're going to see how we can work with these features
0:38
to unleash the full power of Eve validation system
0:41
and model it to suit our own specific needs.
0:44
Now, if you look back at our app.py script
0:49
we realize that we haven't really been working on it for a good while
0:54
most of our time is being spent on the settings file
0:58
and this is nice because we've been changing
1:01
how our service responds to requests updating its schema
1:06
endpoint configuration, everything we've done it's been always a declarative thing,
1:12
we just updated our settings files,
1:14
but now that we want to extend the validation system features set
1:19
we need to write some code, and this is probably very exciting.
1:22
So let's start by important from eve.io.mongo
1:33
as you can see, the eve.io.mongo name space
1:38
exposes a validator class, this is the class used by Eve by default.
1:44
And you see, it is stored within the Mongo name space,
1:48
which already hints at the fact that
1:51
you can have probably more than one validator
1:55
maybe a SQL data layer will be using its own validator,
1:58
which makes sense if you think about it.
2:01
Now that we have a validator class, we want to subclass it.
2:07
Let me save these, as you can see, the server has restarted here,
2:11
and how do I use my validator to replace the standard one,
2:16
well, this is super easy, all I have to do is pass it to my instance.
2:27
So this is how I replace the standard validator
2:32
coming in this case with the Mongo data layer with a custom one,
2:37
right now we aren't really doing anything,
2:40
my validator here is exactly the same as the in-house validator, so to speak.
2:45
Let's, see how we can improve on it.
2:48
Just for fun, let's assume that we're really interested
2:51
in only accepting odd numbers for a certain field,
2:54
and we want to build a custom rule for that.
2:56
We want to be able to go to our settings file,
3:00
pick our age field here and say,
3:04
yes, it is an integer, but look, we also want this integer to be odd.
3:13
So we want the rule like this one is odd true,
3:18
which means age must be an odd integer,
3:23
let's just get rid of this coerce function here just to avoid confusion.
3:27
Let's, go back and let me paste the code for this validation,
3:34
here it is, so as you can see, the way you create a new rule,
3:39
is defining a private function, you can tell it is a private one
3:43
because it has this underscore at the beginning,
3:46
which is a convention in Python for private functions within a class.
3:49
And then you have the validate keyword,
3:51
and then another underscore and then actuall rule name
3:57
so validate is odd. Of course it is a class function,
4:00
we're accepting this is odd, which is a boolean,
4:04
and then the field and value for the field
4:07
which we have to validate against.
4:10
Implementation is very simple, it is just the test
4:12
if the number must be actually odd and it isn't, then set an error.
4:18
So here you see how you set an error,
4:20
you just invoke the error method you pass the field
4:23
and the description for the error, and that's it.
4:28
So let's save, server restarts,
4:32
and let's go to Postmen and see what we've done.
4:35
So here I'm posting last name and age,
4:39
last name I'm adding it because it is required if you remember
4:42
and age is 18, let's try to post this.
4:47
And we get an error, unprocessable entity,
4:49
and as you can see, age value must be an odd number.
4:54
Let's try with 19— good.
5:01
We now know how we can define custom rules
5:04
and apply them to whatever field we need.
5:06
But what if we want to the define custom types instead?
5:11
Let's go to our settings file and look at this email field.
5:15
It is a string and we are applying our regular expressions rule against it,
5:20
it works fine, but if we had more email fields,
5:23
and maybe in other endpoints in our service,
5:27
every time we'd need to copy and paste all this stuff here
5:30
which is also prone to errors,
5:32
it would be much better if we could define a type email
5:36
this way we would not need to type any regular expressions
5:40
and our type would be reusable anywhere
5:44
even in different services in our microservices network maybe.
5:50
We can do that, let me save this type definition and go back to our app.
5:54
The way we define a custom type
5:58
is very similar to how we define a custom rule,
6:02
_validate type,
6:06
now the intellisense here is already hinting at how the Mongo validator
6:12
is extending the base validator class
6:15
as you can see all these types here are Mongo types,
6:20
So let's define our email as a class method,
6:32
this is how you define a custom type, let me paste the actual code.
6:37
So if the regular expression is not matched, then set the field error.
6:44
Now, before we say we need to import regular expression module,
6:50
let me save, relaunch.
6:57
Now, if we try this post here, email should be a type,
7:05
you see we get value is not a valid email for the email field.
7:09
Let me try with a valid email.
7:13
Great, back to our editor,
7:18
So here is our code, as you can see,
7:20
a simple class, subclassing the Mongo validator,
7:23
and you can define custom rules or custom types,
7:27
and these are reusable, you can import your specialized class
7:33
whenever you need to,
7:34
If you're building multiple services with Eve,
7:37
you can reuse your class in all of these services
7:41
which is interesting if you're building a micro services network.
7:45
And the way you pass your validator to the Eve instance
7:49
is simply passing it when you instance the class as an argument.