Schema Overview
The OPRA schema is the central contract of every application. It describes every data type, every operation, every parameter, and every response shape in a single machine-readable structure called the ApiDocument. Every transport adapter, every validation step, and every generated client derives its behaviour from this document.
ApiDocument
An ApiDocument is the root of the schema. It is built at application startup from your decorated classes and holds the complete description of your API.
const document = await ApiDocumentFactory.createDocument({
info: { title: 'My API', version: '1.0' },
types: [Customer, OrderStatus],
api: {
transport: 'http',
controllers: [CustomersController],
},
});
The document is serializable to JSON. Every OPRA application exposes it at GET /$schema so clients and tooling can inspect the live contract.
Data Types
The type system is the foundation of the schema. All validation, coercion, and encoding rules are declared on types and propagated automatically to every operation that references them.
OPRA provides four fundamental type categories:
| Category | Decorator / Factory | Purpose |
|---|---|---|
| Simple | @SimpleType() | Extends a built-in primitive with custom coercion and encoding |
| Complex | @ComplexType() + @ApiField() | Class-based composite structure with named fields |
| Enum | EnumType() | Closed set of accepted values |
| Mixin | @MixinType() | Flat merge of multiple complex types |
In addition, mapped types derive new types from existing ones: PickType, OmitType, PartialType, and RequiredType mirror the TypeScript utility type system at the schema level.
See Data Types for the full reference.
API Definitions
Beyond data types, the schema captures the full operation contract for each transport.
HTTP API — controllers, operations, path and query parameters, request bodies, response shapes, and status codes. The schema drives automatic request validation, response encoding, and OpenAPI-compatible documentation.
MQ API — message queue channels for Kafka and RabbitMQ. The schema describes payload types, headers, and optional RPC response shapes.
WS API — Socket.IO event handlers. The schema describes event names, payload types, and acknowledgement types.
Each transport's schema is defined in its own namespace within the ApiDocument and is resolved independently by the corresponding adapter.
Living Documentation
Because the schema is built directly from your TypeScript classes and decorators, documentation is always in sync with implementation. There are no separate Swagger annotations to maintain and no risk of drift between what the documentation describes and what the code enforces.
The $schema endpoint returns the full ApiDocument as JSON. OPRA's code generation tooling reads this document to produce fully typed client libraries — when the server schema changes, regenerating the client surfaces breaking changes at compile time.
Further Reading
- ApiDocument — document structure and factory options
- Simple Types — built-in primitives and custom extensions
- Complex Types — field declarations, inheritance, discriminators
- Enum Types — closed value sets
- Mixin Types — structural composition
- Mapped Types — PickType, OmitType, PartialType, RequiredType
- HTTP API — HTTP controller and operation schema
- MQ API — message queue schema
- WS API — WebSocket schema