Validator
Allows you to define custom logic to determine whether your local data is still valid or if it needs to be refreshed from the remote source using the Fetcher.
Purpose of the Validator
- Data Freshness: Ensures the data served to your application is up-to-date and meets your application’s specific validity criteria.
- Optimizing Network Usage: Prevents unnecessary network calls by using valid cached data when appropriate.
- Consistency Control: Gives you fine-grained control over when to refresh data, enhancing consistency between the client and server.
APIs
Validator
Validator has the following structure:
interface Validator<Output : Any> {
suspend fun isValid(item: Output): Boolean
}- Parameter
Output- Type
Any- Required
- Required
- Description
The type representing your domain data model. For example, if you have a
Store<Int, Post>, theOutputisPost.- Parameter
isValid(item: Output)- Type
Boolean- Required
- Optional
- Description
A suspending function that determines whether the given item is still valid.
Data Flow
- Data Retrieval Request1
Data Retrieval Request
When your application requests cached data from the Store, it first checks the Memory Cache and the Source of Truth to see if the data is available.
- Validation Check2
Validation Check
The Validator's
isValidmethod is called with the cached data as the parameter. - Validity Determination
- Data Update4
Data Update
If new data is fetched, it's stored in the Memory Cache and the Source of Truth for future requests.
Implementing a Validator
You can create a Validator using the Validator.by factory method:
val validator = Validator.by { item ->
// Your custom validation logic here
}Examples
Time-Based Validation
If your application has data that should be refreshed every 24 hours:
val validator = Validator.by { item ->
Clock.System.now() < item.expiresAt
}Versioning
If your application data model changes and you need to invalidate old cached data:
val validator = Validator.by { item ->
item.version == CURRENT_VERSION
}User Authentication
In cases where authentication tokens expire:
val validator = Validator.by { item ->
!item.token.isExpired()
}Best Practices
- Keep Validation Logic Lightweight: The
isValidfunction should execute quickly to avoid slowing down data retrieval. Complex computations or I/O operations should be avoided. - No Side Effects: The Validator should not modify the data or state. It should only assess the validity of the provided item.
- Decide on Validity Criteria: Clearly define what makes data valid or invalid in your application’s context. This could be based on timestamps, data content, user preferences, or other domain-specific factors.