The Phoenix framework does this for forms. It requires a whole system built around a type called a Changeset that describes input parameters, their validity, and how to modify a struct to reflect the valid changes. In practice this ends up tightly coupled to the database layer for simplity.
It's only tightly coupled if you let it be. You can create changesets around any data shape, whether thats connected to your schema' table, a partial view of a table or entirely independent.