Serialization vs validation in Base
Two jobs people conflate: one shapes data crossing a boundary, the other decides if it is allowed.
Serialization vs validation in Base
Serialization and validation both sit at the edge of your worker, both involve decorating your classes, and both deal with data crossing a boundary. That overlap makes them easy to conflate. They answer different questions, though, and keeping them straight makes both easier to use. The short version: validation asks "is this data acceptable?" and serialization asks "what does this data look like on the wire?"
What validation does
Validation is about trust. Data arriving from outside your worker, a request body, a GraphQL argument, cannot be trusted to be the shape your code expects. Validation is the gate that checks it before your logic runs.
In Base, you validate by decorating the fields of a class with rules from the Verify* family. A field can be required, an email, a number within a range, a string of a certain length, a UUID, and many more. The rules read like a description of what the field must be. When data comes in as that class, Base runs the rules, and your handler only sees data that passed. If you need a rule the family does not have, you can register your own.
Validation is a yes-or-no judgment with a reason. The data is acceptable, or it is rejected with a message that says why. It does not change the data; it decides whether the data is allowed in.
What serialization does
Serialization is about representation. Inside your worker you have rich objects: class instances, nested entities, dates, things that are not plain JSON. To send one of those across a boundary (in a response, over RPC) you have to turn it into a wire format, and to receive one you have to turn the wire format back into the object. That conversion is serialization, and its inverse is deserialization.
In Base, you mark what crosses the wire by decorating a class with the serialization decorators: the object that is serializable, and the fields on it that should be included. Serializing then produces a JSON-safe representation of the object, and deserializing reconstructs the object from that representation. Base handles the awkward parts of that conversion, like what to do when an object refers back to itself, so a cycle becomes a clear outcome instead of a crash.
Serialization does not judge the data. It transforms it between your worker's in-memory shape and the shape that travels.
Why the distinction matters
Put them on a timeline and the difference is obvious. Validation happens on the way in, deciding whether to accept data. Serialization happens at both edges, converting data between the wire and your objects regardless of whether it is "good." A value can be perfectly serializable and still fail validation (a well-formed JSON object with an email field that is not an email). And a value can be valid in principle but still need serialization to travel.
They also compose, which is part of why they look similar. The same class can be both validated and serializable, because the decorators describe different aspects of the same fields: one set says what the field must be, the other says how it crosses the wire. That is the Base pattern at work again, one class wearing both descriptions, each read by the subsystem that cares about it.
The mental model to keep
Validation is the bouncer: it inspects incoming data and either lets it in or turns it away, and it never changes what it inspects. Serialization is the translator: it converts your objects to and from their wire form, and it never judges them. You will often decorate one class with both, because acceptable and transmissible are two different things a piece of data needs to be, and Base lets you say each one where the data is defined.