Implementing Message Validation

1. Validating Message Format

LayerCheck
TransportFrame size ≤ limit
EncodingValid UTF-8 / valid binary header
EnvelopeRequired fields present
PayloadType-specific schema

2. Using Validation Libraries

LibraryLangStrength
zodTSType inference, ergonomic
valibotTSTree-shakable, smaller
ajvJSFast JSON Schema
joiJSMature, server-oriented
PydanticPythonServer-side parity

3. Sanitizing Input Data

ThreatAction
XSS (rendered text)Escape on render (DOMPurify)
SQL injectionParameterized queries
Path traversalStrip ../ from paths
Prototype pollutionReject keys: __proto__, constructor

4. Validating Message Types

Example: Discriminated union

const Msg = z.discriminatedUnion("type", [
  z.object({ "type": z.literal("chat"), "text": z.string() }),
  z.object({ "type": z.literal("typing"), "userId": z.string() }),
]);
PatternDetail
AllowlistReject unknown types
DiscriminatorSingle field selects schema
Version tagRoute to right validator

5. Checking Required Fields

ToolSyntax
zodz.string() required by default
JSON Schema"required": ["id","type"]
Manualif (!msg.id) reject()

6. Validating Data Types

TypeValidator
stringz.string()
numberz.number().finite()
UUIDz.string().uuid()
URLz.string().url()
enumz.enum([...])
datez.string().datetime()

7. Enforcing Length Limits

FieldSuggested Limit
Chat text2000 chars
Username32 chars
Channel name64 chars
Total message64 KB

8. Validating Ranges

Example: Numeric range

z.number().int().min(0).max(100); // percent
z.number().gte(-90).lte(90);       // latitude
CheckMethod
Min/Max.min(n)/.max(n)
Inclusive.gte/.lte
Multiple of.multipleOf(n)

9. Using Custom Validators

Example: Refine

const Slug = z.string().refine(s => /^[a-z0-9-]+$/.test(s), "invalid slug");
HookUse
.refine()Boolean check
.superRefine()Multi-issue
.transform()Coerce + validate

10. Handling Validation Errors

StrategyWhen
Drop + logUntrusted traffic
Send error msgTrusted client (UX feedback)
Close 1008 (policy)Repeated abuse
Rate-limit senderCombined with above