When using data and domain models, where does validation take place? Both or just
For example:
class UsersDB():
def create(self, user_data):
# Create user here
return insert_status
def confirm_user(self, token):
if token_date < today_start:
# Token expired, return False
return False
if not self.collection.exists({'token':token}):
# Token doesn't exist
return False
# Confirm user account
self.collection.update_one({}, {})
class UserService():
def __init__():
self.users_db = UsersDb()
def create(self, user_data):
if self.users_db.exists(user_data['email']):
self._set_error(status=409, error='This user already exists.')
return False
if self.users_db.create(user_data):
EmailService().send_registration_email(user_data)
AuditService().add_event('registration', ....)
else:
self._set_error(status=500, message='Unable to create user.'
return False
Now, in the UsersDB.confirm_user(), if this method fails, it's impossible to determine why the method call fails, be it due to the non-existant token or the expired token. However, this is validation that I don't necessarily want mixed in with the business logic. I'd prefer to keep validation within the UsersDB wrapper.
Similarly, if I wanted to do some more advanced validation on the user_data parameter passed through to UserService.create(), then I'd need to do it at the UserService level in order to get any meaningful feedback to the user.
Should I just separate validation out of the UsersDB object and do the validation within the UserService methods before passing over to the UsersDB object, or is there a problem with the design that needs addressing?
Ideally, I'd like to keep the validation out of UserService so that it only handles calls to other services, but I'm not sure if that's a good idea.