RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Validation with view models
Lecture: Adding validation to APIs (never trust input)
Login or
purchase this course
to watch this video and the rest of the course contents.
0:01
Let's come back to our auto API and make this a little bit more realistic; so it looks like we've got a renderer stuff
0:09
working really well with the negotiate stuff, I think we've got the restful components working great with our http verbs
0:15
our response status codes, things like that. But, still not very realistic, so if we look here, I think this is solid
0:22
you ask for all the cars you get all the cars. Here you ask for a particular one, and if it doesn't exist, you get a 404, great.
0:29
But the farther down we go, it gets the less good, like notice this part about validation.
0:35
We're taking the arbitrary dictionary submitted as a json object back to our view here, and then we're just going that's probably a good car.
0:41
No, that's probably not a good car, we should not be trusting user input here, now to some degree in the database, when we get to the data layer,
0:49
we can model it such that certain types are required, so for example the price must be a number, right
0:54
it can't be just anything, right or that the name is required like these things can be modeled in database constraints.
1:01
We probably don't want to count on that, right if we count on the database
1:05
to actually be the validation layer, we're going to get like sqlalchemy errors as the thing we tell them that went wrong, and that's not great
1:12
we'd much rather say hey, this number that you've submitted has to be between this and this, right this thing must be of this type, and so on,
1:21
so we need to add the validation and for a moment I'm going to make this method worse, not better by actually putting all the validation here,
1:29
because right now where does it go, right, maybe, maybe it goes in from the car, right from dictionary bit that parses it
1:36
and that would not be a bad choice in this particular case, we could put it there, we could have a different exception type that catches the errors
1:44
to me, let's just look at the car real quick. The car is, it's really supposed to be the database object, right
1:50
it's suppose to know what it fields are and so on, and so we model this in sqlalchemy,
1:55
it's really going to represent the sqlalchemy thing, so maybe even this like we probably don't even want this year, so ideally we take this way
2:01
rather than leave it here, at a minimum we need to rewrite this because it turns out if the dictionary contains something that's not listed here
2:09
it's going to crash, as well as if the dictionary omits something like the price for example, it's going to crash as well.
2:16
So this needs some work, right and we could probably move that out of the cars responsibility as well.
2:23
Let me just go and put some validation here we're going to leave this part in, but for example we want to check that hey, the price is valid
2:31
we want to check that it has a name and things like that. Now instead of me typing that all in, let me just paste a bunch of rules here
2:37
and let's do a little trick here, new car, let's rename this, back to car. All right, so for example, what can we check,
2:49
let's suppose we want to be able to give more than one error, like hey these three things were wrong with your submitted post, okay
2:55
so over here, we're going to say if you did not set the last scene, like this is the date time value for what is supposed to be there,
3:05
that's required, that's an error, if you don't set the name, that's an error, or if it's empty right, this will also test if it's empty.
3:12
If we want a check if it's only not there, like is none, right, we could do something like this if it were allowed to be empty but must be present,
3:19
but we'll just go like this, the brand has to be there, the price has to be set, the price cannot be negative right,
3:25
you can't have people pay you to buy the car or whatever; similarly, the year has to be a positive number
3:34
it's got to be reasonable like 1900 until present plus one year, things like that. But you can see there's a decent amount of validation here
3:44
and I would contend that this is just part of it, this is only a little bit of it,
3:48
now like I said, the database will catch some things that are out of step
3:52
as well as when we parse it, we'll be able to do a little bit of work there as well. But now let's just start to look at this method.
3:59
This is not amazing, right, I mean it's doing all this work and we really just wanted to kind of do this, this is sort of the point,
4:06
but so much other stuff going on that it's obscured by that so what we're going to do in this chapter is
4:14
we're going to add another layer that's at play here, so something I'm going to call view models
4:20
and the role of these view models will be to take the inbound data whatever that means, right, like this if it comes off of the url
4:26
that's also a part of it, we could take those things together and do the parsing and the validation and all of that
4:34
and provide kind of the final result to this method to do whatever it's going to do with it right,
4:40
like then hand it off to the repository, and things like this. And that makes it much easier to test, we can test the validation
4:46
by testing the view models, it will make our APIs much cleaner by having one concise common clear repeatable way to do validation
4:54
and if we want to add— I would at some point get tempted to go okay no more validation, it's just making this a mess
5:02
and I don't want this method to be like only validation, alright, but if you move that validation somewhere else,
5:08
well then you can go crazy and put all sorts of rules over there and it doesn't clutter up the reading of the code.