Skip to main content

Parse, don't validate

Don't pass raw input through your app and hope every caller behaves.

Parse at the edge, reject bad data early, and work with a value that already means something.

That gives you a smaller surface area for bugs and a simpler program inside the boundary.

// raw input in, typed value out
const Email = Schema.String.pipe(
  Schema.pattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
  Schema.brand("Email")
)

type Email = Schema.Schema.Type<typeof Email>

const parsed = Schema.decodeUnknownSync(Email)(input)
// bad input stays bad at the edge
const createUser = (input: unknown) =>
  Effect.gen(function* () {
    const body = yield* Schema.decodeUnknown(BodySchema)(input)
    return yield* Users.create(body.email)
  })
// after parsing, the rest of the app gets to assume shape
function sendReceipt(email: Email) {
  return Mailer.send(email, "receipt")
}

The point is not to be clever.

It's to turn "maybe valid" into "valid enough to use" before the program gets interesting.

References

Quick find

Search the garden