mardi 5 novembre 2019

Pattern for unvalidated data, validated data and validation

In my Ktor REST API, I receive JSON. This is conveniently deserialised for me into simple data classes by kotlinx.serialization. Before I can proceed using this data I have to apply some validation. Then I can pass it on to to other parts of the code.

I would like a clear separation between deserialised but unvalidated data, the validation itself, and validated code.

For example, I have something to the effect of:

@Serializable
data class Input(val something: Int)

fun Input.validate() {
    if(something < 5) { throw WhateverException("invalid") }
}

But there's a few issues with this: When receiving an instance of Input anywhere, I can't be sure it's been validated already, so to be safe I'll call validate() again.

So, to avoid this I would like for validate() to return some version of Input that tells me the data is valid, and so that I can have method signatures in my codebase that accept validated data only.

I know I can copy the class Input to a private one called ValidatedInput and have validate() return that, but that looks like code duplication. (I will end up having dozens of classes like Input.) Also that will prevent be from having an interface specifying Input to have the validate method and have it return something like Validated<Input>

How do I design my classes and methods to clearly express this separation, and without repeating code?

Aucun commentaire:

Enregistrer un commentaire