3 ms·
One tangential complaint: func validateUser(user User) error This is a bad way to validate data. It generally means that any new data added to this type w
by kevincox 3y ago
One tangential complaint:
func validateUser(user User) error
This is a bad way to validate data. It generally means that any new data added to this type won't be validated by default. It isn't too bad because it is a typed native data structure (must worse in things like JS where extra fields can slip in from the JSON) but it is better security practice to parse the data rather than just looking at it. So it would look something like this
func validateUser(user User) (error, User)
Then the function carefully extracts and validates the input before copying it to the output. Anything that it doesn't know about doesn't get copied. This can be thought of as "whitelist validation" rather than "blacklist validation".
Parse, don't validate.
- dack 3y agoif you're going to "parse, don't validate" then the signature should probably be func validateUser(user UnvalidatedUser) (error, User) this way, you can't accidentally forget to validate your user before using it in the rest of your code
- kamray23 3y agoIf we're going that route, just forbid making User objects which are not valid. Hide the fields, force the instances to be immutable, validate in the constructor, problem solved. Does not work in things with duck typing or anything remotely resembling the two most used programming languages in new projects in the industry. But for traditional statically typed languages, it's a good solution. Now a function taking in a user is literally incapable of ever taking in an invalid user, assuming your tests for the class are good and pass.
- codethief 3y agoI have always liked this approach and, recently, I came across a term for it: "type tightness"[0]. I gotta say, it really stuck with me. [0]: https://www.ecorax.net/tightness/ https://www.ecorax.net/tightness/
- turboponyy 3y agoExactly - if you have Xs that are foolike, and Xs that are barlike, the perhaps you should have Yz and Zs instead. Further, if you want to validate that your X is barlike, all you have to do now is make sure you have some function f : Y -> Z. If you want to scrutinize your validation logic, then you need only look at all functions of that specific type in your program. Admittedly, go is probably not a language with the best support for these kinds of constructs.