I don’t try to re-implement full JSON Schema in Go, but I do like returning validation errors that are easy for clients to render. The pattern is: decode into a struct, validate required fields and invariants, and return a slice of {field, message} issues. This gives you a stable contract: the frontend can highlight fields without parsing English strings. I keep the validation separate from the handler so it’s testable and so the handler remains a thin adapter. For more complex domains I’d pull in a validation library, but the “hand-rolled issues array” scales surprisingly well for typical CRUD APIs. The important detail is consistency: every endpoint should return the same VALIDATION_ERROR code and the same issue shape. That uniformity is what makes client code simple.