domainstack-schema
OpenAPI and JSON Schema generation for the domainstack full-stack validation ecosystem.
Overview
domainstack-schema provides tools to generate OpenAPI 3.0 schemas and JSON Schema (Draft 2020-12) from your domainstack domain types. This enables automatic API documentation and validation schemas that stay in sync with your validation rules.
Two Approaches
| Approach | OpenAPI | JSON Schema |
|---|---|---|
| Trait | ToSchema |
ToJsonSchema |
| CLI | domainstack openapi |
domainstack json-schema |
Use the trait approach for programmatic generation and type-safe composition. Use the CLI approach for build-time codegen from source files.
Installation
[]
= "1.0.0"
Quick Start: OpenAPI
use ;
Quick Start: JSON Schema
use ;
Schema Constraints
Supports all field-level validation rules that have direct OpenAPI Schema constraint mappings:
| Validation Rule | OpenAPI Constraint | Example |
|---|---|---|
length(min, max) |
minLength, maxLength |
.min_length(3).max_length(50) |
range(min, max) |
minimum, maximum |
.minimum(0).maximum(100) |
email() |
format: "email" |
.format("email") |
one_of(...) |
enum |
.enum_values(&["a", "b"]) |
numeric_string() |
pattern: "^[0-9]+$" |
.pattern("^[0-9]+$") |
min_items(n) |
minItems |
.min_items(1) |
max_items(n) |
maxItems |
.max_items(10) |
Note: Cross-field validations, conditional rules, and business logic validations (e.g., database uniqueness) don't have direct OpenAPI equivalents. For these, use vendor extensions (see below).
v0.8 Features
Schema Composition
Combine schemas using anyOf, allOf, or oneOf:
// Union type (anyOf): string OR integer
let flexible = any_of;
// Composition (allOf): extends base schema
let admin_user = all_of;
// Discriminated union (oneOf): exactly one match
let payment = one_of;
Metadata & Documentation
Add defaults, examples, and documentation:
let theme = string
.enum_values
.default // Default value
.example // Single example
.examples
.description;
Request/Response Modifiers
Mark fields as read-only, write-only, or deprecated:
let user = object
.property
.property
.property;
Schema Types
Build schemas using the fluent API:
use Schema;
// String with constraints
let name = string
.min_length
.max_length
.description;
// Integer with range
let age = integer
.minimum
.maximum;
// Enum
let status = string
.enum_values;
// Array
let tags = array
.min_items
.max_items;
// Object with properties
let user = object
.property
.property
.required;
// Reference to another schema
let team_member = reference;
Building OpenAPI Specs
use OpenApiBuilder;
let spec = new
.description
.
.
.
.build;
// Export as JSON
let json = spec.to_json?;
println!;
Features
- Type-safe schema generation: Implement
ToSchemaorToJsonSchematraits - Fluent API: Chainable methods for building schemas
- OpenAPI 3.0 compliant: Generates valid OpenAPI specifications
- JSON Schema Draft 2020-12: Standards-compliant JSON Schema generation
- No runtime overhead: Schema generation happens at build time
- Framework agnostic: Works with any Rust web framework
Examples
Basic Usage
See examples/user_api.rs for a complete example demonstrating:
- Multiple schema types (User, Address, Team)
- Validation constraint mapping
- Schema references
- Array constraints
v0.8 Features
See examples/v08_features.rs for advanced features:
- Schema composition (anyOf/allOf/oneOf)
- Metadata (default/example/examples)
- Request/response modifiers (readOnly/writeOnly/deprecated)
- Vendor extensions for non-mappable validations
Scope & Positioning
What this crate does:
- Generates OpenAPI 3.0 component schemas for domain types
- Generates JSON Schema (Draft 2020-12) documents
- Maps field-level validations to schema constraints
- Provides type-safe schema builders
- Exports to JSON/YAML
What this crate does NOT do:
- API paths/operations (GET /users, POST /users, etc.)
- Request/response body definitions
- Security schemes or authentication
- Full API documentation generation
Positioning: domainstack-schema focuses on schema generation for domain types. Full OpenAPI spec generation (paths, operations, security) is intentionally out of scope and may be addressed in a separate crate.
Handling Non-Mappable Validations
Some validation rules don't map cleanly to OpenAPI Schema constraints:
// Cross-field validation - no OpenAPI equivalent
// Conditional validation - no OpenAPI equivalent
// Business logic - no OpenAPI equivalent
async
Solution: Use vendor extensions to preserve validation metadata:
object
.property
.extension
This maintains a single source of truth while acknowledging OpenAPI's expressiveness limits.
Related Crates
| Crate | Purpose |
|---|---|
domainstack |
Core validation library |
domainstack-derive |
#[derive(Validate, ToSchema)] macros |
domainstack-cli |
CLI for Zod, JSON Schema, OpenAPI generation |
CLI Alternative
For build-time codegen from source files (without implementing traits), use domainstack-cli:
# Generate JSON Schema from Rust source files
# Generate OpenAPI spec from Rust source files
# Generate Zod schemas for TypeScript
Documentation
- JSON Schema - Complete JSON Schema generation guide
- CLI Guide - CLI codegen for Zod, JSON Schema, OpenAPI
- API Docs - Full API documentation
License
Licensed under MIT OR Apache-2.0.