-
Type:
New Feature
-
Resolution: Won't Do
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
-
1
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Description
Use Case
As a Node.js developer using the MongoDB driver with TypeScript, I want to pass a Zod schema (or its JSON Schema output) directly to db.createCollection() and db.command({ collMod }) and have it produce a working MongoDB $jsonSchema validator, so that I can use a single source of truth (my Zod schema) for both application-level type safety and database-level validation, without hand-writing a transformer to bridge the gap between standard JSON Schema and MongoDB's restricted dialect.
User Experience
- Developers can supply a Zod schema (Zod v4+, which ships z.toJSONSchema()) when creating or modifying a collection and get a valid $jsonSchema validator applied without manual conversion.
- The driver transparently strips/translates JSON Schema keywords MongoDB does not support ($schema, $ref, $defs, format, default, contentEncoding, etc.) and maps type to bsonType where appropriate.
- Developers can opt into BSON-specific types (objectId, date, long, decimal, binData) via Zod metadata (.meta({ bsonType: '...' })) and have those round-trip correctly.
- Clear, actionable errors when a Zod schema produces output incompatible with $jsonSchema (e.g., recursive $ref that cannot be inlined).
- Not a bug — this is a developer-experience enhancement. Today users either roll their own converter or pull in an unofficial third-party library; both fragment the ecosystem and frequently produce silently-broken validators (e.g., format: "email" is dropped by Mongo and the constraint disappears).
Dependencies
- Upstream: Zod v4+ as a peer/optional dependency (or document the integration without taking the dep). z.toJSONSchema() API surface should be considered stable before we couple to it.
- Downstream: DOCSP for documentation; potential coordination with mongoose and community ODMs (e.g., Typegoose) so users aren't routed through conflicting recommendations.
- Server-side $jsonSchema capabilities are version-dependent (e.g., encrypt, certain BSON types). Need to confirm minimum supported server version for any features exposed.
Risks/Unknowns
- Silent constraint loss: Standard JSON Schema keywords like format (used by z.email(), z.url(), z.uuid()) are ignored by MongoDB. Naively passing through Zod's output produces a validator that appears to enforce these but does not. We must either translate to pattern regex equivalents or surface a warning.
- Drift from Zod's output shape: Zod's JSON Schema emitter may change between minor versions; transformer must be defensive.
- Discriminated unions / z.record() / refinements: These produce schemas that are technically valid JSON Schema but may hit edge cases in Mongo's parser. Needs a test matrix.
- Performance: Validator translation should happen once at collection-creation time, not per-write — confirm no hot-path overhead.
- Cross-driver alignment: Other drivers (Python's PyMongo, Go, Rust, C#) do not have an equivalent helper. Worth raising with dbx whether a shared spec for "ODM-agnostic JSON Schema → $jsonSchema translation" makes sense, or whether this should remain a Node-driver-only convenience. If Node ships this and others don't, document the divergence.
- Documentation opportunity: Existing docs explain $jsonSchema and JSON Schema separately but not the gap between them. This is a chance to publish a definitive guide.
Acceptance Criteria
Implementation Requirements
- New helper exported from the driver (e.g., toMongoJSONSchema(input)) that accepts either a Zod schema or a plain JSON Schema object and returns a MongoDB-compatible $jsonSchema value.
- Stripping of unsupported keywords: $schema, $id, $ref, $defs, definitions, default, contentEncoding, contentMediaType, examples, deprecated, readOnly, writeOnly.
- Translation of type → bsonType with override via meta({ bsonType: '...' }).
- format: "date-time" on a date-typed Zod schema maps to bsonType: "date".
- Optional formatStrategy: 'strip' | 'pattern' | 'warn' controlling how unsupported format values are handled (default: 'warn').
- Recursive descent into properties, items, additionalProperties, patternProperties, allOf/anyOf/oneOf, not.
- Inline-only output (no $ref/$defs) — surface a clear error if the input contains unresolvable cycles.
- No mandatory dependency on Zod; the helper accepts plain JSON Schema so non-Zod users benefit too.
Testing Requirements
- Unit tests covering each stripped/translated keyword, including nested cases.
- Integration tests against a live MongoDB instance verifying that createCollection with a converted schema accepts valid docs and rejects invalid ones.
- Round-trip tests for every supported BSON type via meta({ bsonType }).
- Test matrix for Zod features: primitives, optionals, unions, discriminated unions, z.record(), z.array(), nested objects, .refine() / .transform() (document what is/isn't preserved).
- Spec test sync: confirm whether server-side $jsonSchema behavior is covered by an existing spec; if not, file a dbx ticket to add coverage.
- Snapshot tests of converter output to catch regressions when Zod's emitter changes.
Documentation Requirements
- DOCSP ticket: new section "Using Zod schemas for database-level validation" under the validation guide.
- API docs for the new helper, including the formatStrategy option and the meta({ bsonType }) convention.
- Migration note for users currently hand-rolling converters or using community packages.
- Explicit list of JSON Schema keywords MongoDB does not support, with recommended substitutions.
Follow Up Requirements
- File DOCSP ticket once API surface is finalized.
- File ticket for mongoose team to consider adopting/aligning with the same converter (if direction is approved).
- Confirm with dbx devs whether other drivers should expose an equivalent and, if not, document Node's divergence in the driver comparison matrix.
- Consider follow-up for converting in the reverse direction ($jsonSchema → Zod) for users introspecting existing collections — out of scope for this ticket but worth tracking.
- Required release: target inclusion in the next minor version; flag in changelog under "new features."