ModuleType object that declares what a domain owns. You don’t write glue code to wire controllers, entities, or jobs together — you list the classes in the appropriate array, and the framework resolves and wires each one through the dependency injection container. Composing a module is the act of collecting a domain’s artifacts in one place; registering it is the act of exposing them to the running app.
How it works
AModuleType from @ooneex/module has one array per artifact kind. Listing a class in an array is the declaration — the framework reads the module, registers each class with the container, and applies its decorators (routing for controllers, @decorator.middleware() for middleware, and so on).
| Array | What belongs here | Resolved as |
|---|---|---|
controllers | HTTP controllers from @ooneex/controller and WebSocket controllers from @ooneex/socket. | Routes registered from each @Route.* decorator. |
entities | TypeORM-backed database entities the domain persists. | Registered with the data source for migrations and repositories. |
middlewares | Request and socket middleware that intercept the domain’s traffic. | Registered via @decorator.middleware() into the pipeline. |
cronJobs | Scheduled jobs the domain runs on a timer. | Registered with the scheduler from each job’s cron expression. |
events | Pub/sub event handlers the domain reacts to or emits. | Registered as subscribers on the event bus. |
Composing a module
Build a module up one array at a time. Each array maps to a kind of artifact the domain owns — nothing more.controllers
Both HTTP and WebSocket controllers go incontrollers. The framework registers each one’s routes from its @Route.* decorators.
entities
List the TypeORM-backed entities the domain persists. Registering them here makes them part of the data source, so repositories and migrations can find them.middlewares
Middleware that intercepts the domain’s requests or socket connections goes here. The framework registers each via its@decorator.middleware().
cronJobs
Scheduled work the domain runs on a timer belongs incronJobs. Each job is registered with the scheduler from its cron expression.
events
Pub/sub handlers the domain reacts to — or emits — go inevents. Each is registered as a subscriber on the event bus.
Registering a module
Composing a module declares its artifacts; registering it exposes them to the running app. A module is registered into a destination module. Theapp destination registers a new module into both AppModule and SharedModule — wiring handled for you by module:create. Once registered, the app has access to every artifact the registered modules declare.
Best practices
- One domain per module. A module is a vertical slice. Keep the order domain in
OrderModuleand the auth domain inAuthModule— don’t mix unrelated concerns in a single object. - List only what the domain owns. An array entry is a declaration of ownership. If a class belongs to another domain, it should be declared in that domain’s module, not duplicated into yours.
- Prefer the generators. Scaffolding artifacts with the
:createcommands auto-registers them in the right array, so the module stays in sync without manual edits. - Keep cross-module dependencies explicit via shared. When two domains need the same artifact, declare it once in the shared module rather than reaching across module boundaries —
SharedModuleis the seam for cross-cutting code. - Let registration handle exposure. Compose the domain in its own module and register it through
app; avoid hand-wiring artifacts intoAppModuleoutside the generated flow.
Learn more
- Module overview — what a module is and why Ooneex composes by domain.
- Module structure — how a module’s files are laid out on disk.
- Dependency injection — how the container resolves and wires declared artifacts.
- Routing — how
@Route.*decorators turn controllers into routes. - Events — writing the pub/sub handlers you list in
events. - WebSockets — socket controllers and middleware that share the
controllersandmiddlewaresarrays.