modules/<kebab-name>/ and runs as its own process. Running ooneex microservice:create scaffolds the same definition-plus-config skeleton as a plain module, then adds the pieces a service needs to boot and deploy on its own: an entrypoint, an application start hook, its own environment config on a distinct port, role configuration, and a Dockerfile. Unlike a module, a microservice is not registered into AppModule or SharedModule — it runs independently and is wired to the rest of the system through networking config. This page walks through that layout file by file.
See Overview for what a microservice is, Networking for how it is declared and reached, and Composition for how its internals combine. For the plain-module skeleton it builds on, see Module structure.
Layout
A freshly createdbilling microservice looks like this:
src/ (controllers/, services/, repositories/, entities/, middlewares/) are created on demand as you generate artifacts into the service — a new microservice starts with just src/BillingModule.ts, src/index.ts, and src/OnAppStart.ts.
Generated files
Every file below is written bymicroservice:create. The first group mirrors a plain module; the rest are unique to microservices because they run as their own process.
| File | Purpose |
|---|---|
src/<Pascal>Module.ts | The module definition. Exports a ModuleType whose arrays declare the service’s artifacts. |
src/index.ts | The microservice entrypoint — the same template as the app entrypoint, pointed at <Pascal>Module instead of AppModule. |
src/OnAppStart.ts | An application start hook that runs when the microservice boots. |
<kebab-name>.yml | Module config with type: "microservice". |
.env.yml | The service’s own environment config: a distinct app.port, cache / pubsub / rate_limit Redis URLs, and a Postgres database.url. |
roles.yml | The role configuration for the service. |
Dockerfile | Lets the service be built and deployed independently. |
package.json | Workspace package named @module/<kebab-name> with test and lint scripts. |
tsconfig.json | TypeScript config. |
tests/<Pascal>Module.spec.ts | Mirrored test asserting each ModuleType array exists. |
src/<Pascal>Module.ts — the module definition
The heart of the service. It exports a single ModuleType object whose arrays declare what the service contributes. You register each artifact you create by adding it to the matching array.
<kebab-name>.yml — module config
The config file marks the unit as a microservice. The type field distinguishes it from the other kinds of unit (api, microservice, design, spa, sdk, module); for a microservice it is set to microservice.
Files unique to a microservice
A plain module stops at the definition, config, package, tsconfig, and test. A microservice adds the files it needs to run and ship on its own:| File | Why a microservice needs it |
|---|---|
src/index.ts | A module is mounted inside the app; a microservice is its own process, so it needs an entrypoint to start. |
src/OnAppStart.ts | A boot hook to run setup when the service starts standalone. |
.env.yml | The service runs on its own port and connections, so it carries its own environment rather than sharing the app’s. |
roles.yml | Role configuration scoped to the service. |
Dockerfile | The service is built and deployed independently of the API. |
src/index.ts and src/OnAppStart.ts
src/index.ts is the entrypoint that boots the service. It is the same template as the app entrypoint, but it loads <Pascal>Module instead of AppModule. src/OnAppStart.ts is the start hook the entrypoint invokes — application setup that should run once when the microservice boots.
.env.yml — its own port
Because a microservice is a separate process, it gets its own environment config with a distinct app.port. Port 3000 belongs to the API; microservices start at 3001 and each new service picks the next free port. The file also carries the service’s cache, pubsub, and rate-limit Redis URLs and its Postgres database.url.
Not registered in AppModule
A microservice is not added toAppModule or SharedModule — it runs standalone rather than being mounted into the main app. Instead it is declared for networking in modules/app/app.yml and the root .env.yml, which is how other services discover and reach it. See Networking for that wiring, and Deployment for building and shipping the service from its Dockerfile.