lasseebert / validation

Validation library for Elixir
https://github.com/lasseebert/validation
14 stars 1 forks source link

Type coercion #13

Open lasseebert opened 7 years ago

lasseebert commented 7 years ago

This is meant as a discussion on whether or not Validation should support type coercion.

It is my belief that many use cases where one needs validation of input data, coercion is also needed. I think especially of posted html forms where every value is a string.

solnic commented 7 years ago

Coercion and validation goes hand in hand. The tricky part is that coercion must be safe and always expect that something can go wrong, but should not result in a crash.

In dry-validation coercion is a separate, optional step, which is applied to input prior applying schema rules. The tricky part is to try to coerce all values according to type specification and return everything back, even when some coercions failed (and in that case the original values must be returned back so that they can be validated).

I would recommend implementing coercion as part of this lib, with the intention of extracting it into a separate library (it will become big quite fast, you'll see).

certainty commented 7 years ago

Hmm to me coercion is very distinct responsibility. It is a mapping from one type to another. Validation, at least to me, is enforcing invariants on (typed) values. I would assume that the coercion was done before, if needed, either manually or as part of a parsing step to reify those values.

I can see that there is a conceptual intersection when you make sure that the input type is actually convertible to the output type by making sure for example that it follows some format. It looks similar but serves a very different purpose.

To me it appears to be quite an increase in complexity with unclear advantages. My 2 cents :)

solnic commented 7 years ago

I agree, that's why I mentioned that it's a separate step before applying rules. It's so common that for convenience it's better to be able to express both type specs and validation rules in a single place, but under the hood it's treated separately. If we were to follow theoretical correctness in the API, and tell people to specify coercion and validation in two different places, then I can guarantee that people will hate it. Imagine a schema with 300 fields, and having to define coercion types 300 times, then validation rules 300 times (we have people with such big schemas using dry-validation already!) - this would be a massive code bloat.

lasseebert commented 7 years ago

Addin a pre-processor step will also make rules simpler, since rules no longer needs to change data. (If they would change data, they would not be rules, but preprocessors).

Rules then just accept a params map and return an error map. The schema is then responsible for merging the errors from different rules together.

Right now rules accept a %Result{} and return an updated result. This makes them able to update the data inside the result, which could make things complicated.

lasseebert commented 7 years ago

Waiting for https://github.com/lasseebert/validation/issues/21 closed