I’d recommend Scott Wlaschin’s excellent book “Domain Modelling made Functional”. The examples are in F# but the concepts apply much more broadly.
That way, you don't need nearly as much defensive coding re: null checks etc. because the data has gone from 'some client typed some value in an input box, hope its valid' to 'this is an Address line that has been confirmed to be valid structure to pass to downstream systems'.
Pit of success is so much better than peak of success, and much easier to get in a static typed functional language vs. an OO language in my experience.
This article is very much in the same vein.