So far I am using colander to validate the data in my aiohttp application.
The problem I face is that I don't know how to do "deep" validation.
Given the following schema:
import colander
class User(colander.MappingSchema):
username = colander.SchemaNode(colander.String())
password = colander.SchemaNode(colander.String())
confirmation = colander.SchemaNode(colander.String())
I do both validate that the input datastructure has all the required fields are there (constraints are minimal for the sake of clarity) but I also need to check that:
username
is not already taken by another userpassword
andconfirmation
are the same
So in my controllers, the code looks like the following pseudo code:
def create_user(request):
user = await request.json()
schema = User()
# do schema validation
try:
user = schema.deserialize(user)
except colander.Invalid, exc:
response = dict(
status='error',
errors=errors.asdict()
)
return json_response(response)
else:
# check password and confirmation are the same
if user['password'] != user['confirmation']:
response = dict(
status='error'
errors=dict(confirmation="doesn't match password")
)
return json_response(response)
# check the user is not already used by another user
# we want usernames to be unique
if user_exists(user['user']):
response = dict(
status='error',
errors=dict(username='Choose another username')
)
return json_response(response)
return json_response(dict(status='ok'))
Basically there is two kinds of validation. Is it possible to have both logic in single colander schema? Is it a good pattern?