Open NoPhaseNoKill opened 11 months ago
(This is just a quick answer, I'll devote more time in a thorough answer coming week, but I wanted to give some initial thoughts)
First of all, I would suggest moving away from your ValidationResult
, and instead use regular Either
. In fact, your type could be represented as Either<Failure, Unit>
(I use Unit
since you have no information attached to Success
). This is only for cutting quite some code, you can also make Arrow aware of your own error types as described in the documentation.
By using Either
(or making Arrow aware of your type), you can use the DSL from beginning to end. For example, you could rewrite:
// just to clarify
val success: Unit = Unit
class AccountTypeOneOnlyValidation: ValidationStrategy {
override suspend fun validate(
requestContext: RequestContext,
): ValidationResult = either {
ensure(requestContext.account.type == AccountType.AccountTypeOne) {
ValidationResult.Failure.AccountState.AccountTypeTwoInvalid
}
success
}
}
Although I don't fully understand your Aggregator
, note that it could be implemented much easier as a pipeline.
class ValidationResultAggregator(private vararg val strategies: ValidationStrategy) {
suspend fun aggregate(requestContext: RequestContext): List<ValidationResult> =
strategies.map { it.validate(requestContext) }.filterInstanceOf<ValidationResult.Failure>()
}
The reason why I don't fully understand is because you're not actually returning information when everything is successful, only the failures. If you want to use that line of reasoning, I would suggest moving to error accumulation instead. The idea is that you return Either<List<Failure>, Success>
, where the list accumulates all the errors. Using the Either
DSL you can do it as follows:
suspend fun aggregate(requestContext: RequestContext): Either<List<ValidationResult>, Unit> = either {
mapOrAccumulate(strategies) { it.validate(requestContext) }
success
}
Thanks for the reply, will have a go at implementating your suggestions and get back to you after I've done that. Appreciate the fact that you even responded with a 'quick' answer - absolutely no rush :)
Hey there,
Firstly I'd like to say thank you a lot for the creation of the library. This is the first time I've leant on functional programming 'paradigm', but it seemed like the appropriate tool in the particular problem I'm trying to solve. Bare in mind, like I said, I'm relatively new to it all, so feel free to correct me on any terminology I'm misusing/misunderstanding.
There appeared to be a similar issue previously asked, but because I'm new to it all, wasn't sure how to apply this to my problem (see here: https://github.com/arrow-kt/arrow-website/issues/161).
Context
Context - The problem
Context - Contraints influencing current decisions made
Example of how I'm using arrow-kt (have included the questions I want to ask after this)
Note: I have included test cases for all scenarios, which hopefully highlight my requirements/constraints. If you have questions/this isn't clear enough, please feel to reach out.
Questions
1) It feels clunky having to check Either.Left or Either.Right and return a validation result based off of that in each of the validation classes. Is there a better way to do this? 2) Considering I am using the DSL for either inside of each validation, and basically repeating the same thing in each of my validation files, it feels like I'm using this wrong. It feels like I could utilize both a DSL, and/or some type other than Either to represent this. I haven't quite understood how to do this from the docs/the above issue. Are you able to help me/provide examples based on my code? 3) Do you have any general suggestions for code improvements? I know this isn't necessarily in the scope of your project, but considering I have found that you used to have something similar to a ValidationResult (replaced by Either to my knowledge) - I suspect you've run into similar problems and may have some experience in the area 4) Are there any other improvements/suggestions you have which may completely restructure how I would do this/solve the problem? 5) Because I'm still feeling this out, I don't know what I don't know haha. Is there anything else (such as articles/further learning/knowledge/experience in the project) you'd like to provide where you feel as though the concepts are important and may either bite me in future/are something I should be aware of now?
edit: Cleanup typos