The edge is the first layer that touches an untrusted value: the middleware that runs after body parsing and before your handler. Validate there and everything downstream — controllers, the store, the driver — works with values of known type and range. Validate later and every layer has to defend itself, which in practice means none does.
Three costs come from skipping it. The first is wrong status codes: year: "twenty" travels to the store, fails a cast, and surfaces as a 500 — the API telling a client that the server is broken when the client sent nonsense. The second is mass assignment, where req.body spread into a record lets anyone add fields you never intended and {"title":"Go","role":"admin"} becomes a privilege escalation; a schema that lists the accepted fields and drops the rest closes that hole by construction. The third is one message per round trip instead of all of them at once.
The edge is also where types enter the program: query strings are always strings, so ?limit=20 arrives as "20", and a Number() call in each handler is one coercion written many times, differently.
None of this replaces the layers behind it. A schema can tell you an ISBN has 13 digits, but only the handler knows whether it is already taken, and only a unique index guarantees that under concurrency. Skip the edge, though, and one of those two writes the error message: a driver's duplicate-key exception is not something a client should read.