schema-dsl project best practice examples
Use this page when you are ready to organize schema-dsl in an application rather than in one demo file. It shows where to place shared schemas, how route handlers reuse them, and how to avoid recreating schemas for every request.
Recommended project structure
Complete sample code
1. Define Schema (schemas/user.js)
2. Define Schema (schemas/order.js)
3. Unified export (schemas/index.js)
4. Use in routing (routes/user.js)
5. Main application entrance (app.js)
Performance comparison
❌ Not recommended: convert every request
Performance Issues:
- ❌ Perform DSL → JSON Schema conversion on every request
- ❌ 1000 requests = 1000 conversions
- ❌ Performance loss is obvious when concurrency is high
- ❌ If the request changes the schema shape, cache hits become unlikely and memory/CPU pressure rises
✅ Recommended: Convert when project starts
Performance Advantages:
- ✅ 1 conversion on launch
- ✅ 1000 requests = 0 conversions
- ✅ Best performance during high concurrency
Cache and memory boundary
Stable request-time DSL is normally a performance concern rather than a memory leak. When the schema structure is the same, the validator can reuse the compile cache even if a handler creates a fresh object. It is still slower than converting at startup because the DSL object must be normalized again.
The memory risk appears when a long-running service accepts or constructs an unbounded number of unique schema shapes:
The cache works for repeated structures; it is not a substitute for bounding dynamic schema cardinality.
Also avoid creating new Validator() inside normal request handlers. It is not usually a retained-memory leak when the instance is not stored, but it discards the AJV instance and compilation cache for every request.
Summary of usage scenarios
Common mistakes
❌ Mistake 1: Defining schema in routing file
Problem: Creating a new schema object for each request is a waste of performance.
❌ Mistake 2: Defining schema inside a function
Problem: Each time the function is called, a new schema is created, which should be mentioned outside the function.
✅ Correct: defined at the top of the module
TypeScript support
Summarize
✅Best Practices:
- Define all schemas in a separate
schemas/directory - Load when the project starts and convert once
- Used directly in routing without conversion
- Suitable for production environments and high concurrency scenarios
✅Performance Advantages:
- Avoid duplication of conversions for each request
- Schema reuse, smaller memory footprint
- Response time is more stable
✅ Code Advantages:
- Centrally manage all validation rules
- Easy to maintain and modify
- Type safety (TypeScript)
Corresponding sample file
Example entry: best-practices-project-structure.ts
Description: Use a minimal userSchemas object to simulate the centralized definition/routing multiplexing structure and directly verify the two paths of registration and login.