RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Validation with view models
Lecture: Adding validation to APIs (never trust input)
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.