> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ooneex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> A standalone module that runs as its own independently-deployable service, reachable by the app over HTTP.

A microservice in Ooneex is a module that runs as its own process. It is built on the same module system as every other module — it still exports a `<PascalName>Module` of type `ModuleType` from `@ooneex/module` with controllers, entities, middlewares, cronJobs, and events — but instead of being composed into the single app process, it is deployed and started on its own. The main app/API talks to it over the network. The difference is **deployment and networking, not the programming model**.

Like a regular module, a microservice lives under `modules/<kebab-name>/`. Unlike a regular module, it is **not** registered into `AppModule`/`SharedModule`; it owns its own entrypoint, start hook, `Dockerfile`, config, port, and roles, and it is declared as a remote dependency the app reaches by URL.

## Why microservices

* **Same programming model.** A microservice exports the same `ModuleType` shape from `@ooneex/module` — controllers, entities, middlewares, cronJobs, events. If you can write a module, you can write a microservice.
* **Independent deployment.** It is its own process with its own `Dockerfile` and `src/index.ts` entrypoint, so it ships, scales, and restarts on its own schedule — separate from the API.
* **Its own runtime config.** Each microservice carries a distinct `.env.yml` on its own port (the API runs on `3000`; each microservice takes the next free port starting at `3001`) and its own `roles.yml`.
* **Network boundary.** The app calls the microservice over HTTP, so a fault or slow deploy stays contained behind that boundary instead of taking down the whole app process.
* **One CLI to manage it.** Scaffold and tear down a microservice with `ooneex microservice:create` and `ooneex microservice:remove` — no manual wiring.

## How it works

A microservice reuses the module system: it exports a `<PascalName>Module` of type `ModuleType`, the same as a regular module. What changes is everything around the module. It gets its own entrypoint and start hook, runs as its own containerized process on its own port, and is reached by the app over HTTP rather than being composed into `AppModule`/`SharedModule`. The app declares it in `modules/app/app.yml` under a `microservices:` list and resolves its address from an environment variable.

| Aspect            | Regular module                        | Microservice                                                               |
| ----------------- | ------------------------------------- | -------------------------------------------------------------------------- |
| Programming model | `ModuleType` from `@ooneex/module`    | Same `ModuleType` from `@ooneex/module`                                    |
| Deployment        | Composed into the single app process  | Its own process, with its own `Dockerfile` and `src/index.ts` entrypoint   |
| Networking        | In-process function calls             | App reaches it over HTTP                                                   |
| Registration      | Added to `AppModule` / `SharedModule` | Declared in `modules/app/app.yml` under `microservices:`, wired by env var |
| Port              | Shares the API on `3000`              | Its own port, next free starting at `3001`                                 |
| Config & roles    | Shares the app config                 | Owns a distinct `.env.yml` and `roles.yml`                                 |

A microservice is declared in `modules/app/app.yml` as a named remote whose URL comes from the environment:

```yaml theme={null}
microservices:
  - name: "billing"
    url: MICROSERVICE_BILLING_URL
```

The module export itself looks like any other module — same `ModuleType`, same `@ooneex/module` import:

```typescript theme={null}
import type { ModuleType } from "@ooneex/module";

export const BillingModule: ModuleType = {
  controllers: [],
  entities: [],
  middlewares: [],
  cronJobs: [],
  events: [],
};
```

The extra files a microservice owns — `src/index.ts`, `src/OnAppStart.ts`, `Dockerfile`, `.env.yml`, `roles.yml` — are what turn that module into a self-contained, deployable service.

## When to reach for one

Reach for a plain [module](/module/overview) by default: it is composed into the app process and called in-process, which is simpler to build, test, and deploy. Reach for a microservice when a piece of the system needs to deploy, scale, or fail independently of the API — a separate runtime, its own port, its own container, its own release cadence. The code inside stays a `ModuleType` either way, so the choice is about boundaries, not about rewriting your logic.

## Next steps

* [Structure](/microservice/structure) — the files a microservice owns: entrypoint, start hook, `Dockerfile`, `.env.yml`, `roles.yml`.
* [Composition](/microservice/composition) — exporting the `ModuleType` (controllers, entities, middlewares, cronJobs, events).
* [Networking](/microservice/networking) — declaring it in `app.yml`, ports, and wiring the URL through env.
* [Create](/microservice/create) — scaffold one with `ooneex microservice:create`.
* [Remove](/microservice/remove) — tear one down with `ooneex microservice:remove`.
* [Module overview](/module/overview) — the regular, in-process module it is built on.
* [Deployment](/advanced/deployment) — shipping the API and its microservices.
