Use external sources
Data validation can sometimes rely on external sources, a database, an HTTP API, even a file. Akkurate comes with a mechanic of contextual validation to allow using those external sources during validation.
Contextual validation
Remember the code example about Twitter for conditional constraints? We were using the following global variable to query our database:
However, instead of using a global variable, you're probably storing your DAO instance inside a container and injecting it wherever you need.
Akkurate allows you to pass a context to your validator in addition to the validated object. This is done by using Validator<ContextType, ValueType>
to instantiate the validator.
Let's reuse our Twitter example and adapt it with this new feature:
The context type is passed first, then the value type; while the context value is available as the first parameter of the lambda.
Now, when calling our validator, we have to provide an instance of UserDao
before the value to validate:
Keep the same context across multiple validations
You don't need to provide the context for each validation. Especially when you want to provide the context higher in the code hierarchy and let some more specific code provide the object to validate.
You can solve this by currying your validator:
Use multiple contextual objects
When you need to pass multiple objects as a context, create a data class to wrap them:
Use destructuring to write more concise code:
Suspendable validation
If your external source is asynchronous, like an HTTP API, you have to make your validator suspendable by calling Validator.suspendable
.
Let's reuse the contextual validation example based on Twitter and replace the UserDao
interface by UserApi
:
To be able to call the suspendable method existsByUsername
, we have to make our validator suspendable:
Note that suspendable validators can only be called from suspendable functions: