# Getting Started with NestJS (/integrations/nestjs/tutorials/getting-started)



## Implementation steps [#implementation-steps]

<Steps>
  <Step>
    ### Prerequisites [#prerequisites]

    Before you start, make sure you have:

    | Requirement   | Details                                                   |
    | ------------- | --------------------------------------------------------- |
    | Node.js       | 20.11.0 or later                                          |
    | NestJS app    | An existing project, or create one with `nest new my-app` |
    | KubeMQ broker | A running broker reachable on `localhost:50000`           |

    If you do not have a broker yet, start one locally with Docker:

    <RunKubeMQ ports="[50000]" />

    Port `50000` is the gRPC port the transport connects to. The `@kubemq/nestjs-transport` package is built on the native `kubemq-js` SDK, so no HTTP connector flag is required.
  </Step>

  <Step>
    ### Install the Transport [#install-the-transport]

    Add the transport and its `kubemq-js` runtime dependency:

    ```bash
    npm install @kubemq/nestjs-transport kubemq-js
    ```

    Most of the peer dependencies already ship with a typical NestJS project. Install any that are missing:

    ```bash
    npm install @nestjs/common @nestjs/core @nestjs/microservices rxjs reflect-metadata
    ```

    <Callout type="info">
      The package exposes two optional subpath entry points: `@kubemq/nestjs-transport/testing` (mocks for unit tests) and `@kubemq/nestjs-transport/cqrs` (the `@nestjs/cqrs` bridge). They are only needed for those specific features and pull in their own optional peer dependencies (`@nestjs/terminus` for health checks, `@nestjs/cqrs` for the CQRS bridge).
    </Callout>
  </Step>

  <Step>
    ### Register the Module [#register-the-module]

    In your root module, register a global connection with `forRoot` and a named client with `register`. The global connection is shared across the app; the named client is the proxy you inject to send messages.

    ```typescript title="app.module.ts"
    import { Module } from '@nestjs/common';
    import { KubeMQModule } from '@kubemq/nestjs-transport';
    import { OrderHandler } from './order.handler';
    import { OrderService } from './order.service';

    const address = process.env.KUBEMQ_ADDRESS ?? 'localhost:50000';

    @Module({
      imports: [
        KubeMQModule.forRoot({
          address,
          clientId: 'orders-app',
          isGlobal: true,
        }),
        KubeMQModule.register({
          name: 'KUBEMQ_SERVICE',
          address,
          clientId: 'orders-client',
        }),
      ],
      providers: [OrderHandler, OrderService],
    })
    export class AppModule {}
    ```

    The `name` you pass to `register` (here `'KUBEMQ_SERVICE'`) is the injection token you will use to inject the client in Step 6.
  </Step>

  <Step>
    ### Add a Command Handler [#add-a-command-handler]

    Create a handler that responds to the `orders.create` channel. Use `@CommandHandler` for the channel, `@Payload()` to bind the message body, and `@Ctx()` to access the `KubeMQCommandContext`. Returning a value from the method sends it back as the command response.

    ```typescript title="order.handler.ts"
    import { Injectable, Logger } from '@nestjs/common';
    import { CommandHandler, KubeMQCommandContext } from '@kubemq/nestjs-transport';
    import { Payload, Ctx } from '@nestjs/microservices';

    @Injectable()
    export class OrderHandler {
      private readonly logger = new Logger(OrderHandler.name);

      @CommandHandler('orders.create')
      handleCreate(
        @Payload() data: { name: string; total: number },
        @Ctx() ctx: KubeMQCommandContext,
      ) {
        this.logger.log(`Command from ${ctx.fromClientId} on ${ctx.channel}`);
        return { orderId: 'order-123', status: 'created' };
      }
    }
    ```

    <Callout type="warn">
      The handler class must be a NestJS-managed provider. If the decorator never fires, the most common cause is a class that is not listed in a module's `providers` (the class is `@Injectable()` and the module imports `KubeMQModule`). A standalone class instantiated outside Nest will not be wired to the transport.
    </Callout>
  </Step>

  <Step>
    ### Bootstrap the Hybrid App [#bootstrap-the-hybrid-app]

    A NestJS hybrid app serves both HTTP and the KubeMQ microservice transport. Attach the `KubeMQServer` strategy with `connectMicroservice`, start the microservices, then start the HTTP listener.

    ```typescript title="main.ts"
    import 'reflect-metadata';
    import { NestFactory } from '@nestjs/core';
    import { KubeMQServer } from '@kubemq/nestjs-transport';
    import { AppModule } from './app.module';

    const address = process.env.KUBEMQ_ADDRESS ?? 'localhost:50000';

    async function bootstrap() {
      const app = await NestFactory.create(AppModule);

      app.connectMicroservice({
        strategy: new KubeMQServer({
          address,
          clientId: 'orders-server',
          group: 'orders-group',
        }),
      });

      await app.startAllMicroservices();
      await app.listen(3000);
    }
    bootstrap();
    ```

    The `group` option puts the server in a consumer group, so multiple replicas load-balance command delivery instead of each receiving a copy.
  </Step>

  <Step>
    ### Send From a Service [#send-from-a-service]

    Inject the named client by its token and call `send` for request-reply. `send` returns an RxJS `Observable`, so wrap it in `firstValueFrom` to await the single response.

    ```typescript title="order.service.ts"
    import { Injectable, Inject, Logger } from '@nestjs/common';
    import { ClientProxy } from '@nestjs/microservices';
    import { firstValueFrom } from 'rxjs';

    @Injectable()
    export class OrderService {
      private readonly logger = new Logger(OrderService.name);

      constructor(@Inject('KUBEMQ_SERVICE') private readonly client: ClientProxy) {}

      async createOrder(data: { name: string; total: number }) {
        const response = await firstValueFrom(
          this.client.send('orders.create', data),
        );
        this.logger.log(`Command response: ${JSON.stringify(response)}`);
        return response;
      }
    }
    ```

    By default `client.send()` sends a **Command** and `client.emit()` sends an **Event**. To send a Query, Events Store message, or Queue message instead, wrap the payload in a `KubeMQRecord` — see [Usage](/integrations/nestjs/how-to/usage).
  </Step>

  <Step>
    ### Run It [#run-it]

    The repository ships a large examples corpus where every folder is a self-contained NestJS mini-app. The fastest way to see a working command round-trip is the `rpc/send-command` example, which registers a handler and a sender in the same app:

    ```bash
    cd examples
    npm install
    npx tsx examples/rpc/send-command/main.ts
    ```

    Expected output:

    ```text
    [SendCommandExample] KubeMQ microservice started
    [CommandService] Sending command...
    [CommandHandler] Received command on nestjs-rpc.send-command: {"action":"create-user","name":"Alice"}
    [CommandService] Command response: {"executed":true,"action":"create-user"}
    ```

    To see all five handler decorators (`@CommandHandler`, `@QueryHandler`, `@EventHandler`, `@EventStoreHandler`, `@QueueHandler`) exercised in one application, run the `decorators/all-handlers` example:

    ```bash
    npx tsx examples/decorators/all-handlers/main.ts
    ```

    <Callout type="info">
      Every example reads the broker address from the `KUBEMQ_ADDRESS` environment variable and falls back to `localhost:50000`. To target a remote broker, export the variable before running: `KUBEMQ_ADDRESS=my-broker:50000 npx tsx examples/rpc/send-command/main.ts`.
    </Callout>
  </Step>

  <Step>
    ### Next Steps [#next-steps]

    <Cards>
      <Card title="Usage" href="/integrations/nestjs/how-to/usage" description="Commands, Queries, Events, Events Store, and Queues with the handler decorators and KubeMQRecord builder." />

      <Card title="Module Configuration" href="/integrations/nestjs/how-to/module-configuration" description="forRoot / forRootAsync, register / registerAsync, forTest, and multi-broker setups." />

      <Card title="Concepts" href="/integrations/nestjs/concepts" description="How the transport maps NestJS message patterns onto KubeMQ channels and contexts." />

      <Card title="Reference" href="/integrations/nestjs/reference/configuration" description="Configuration options, the full decorator/context API, and the error catalog." />
    </Cards>
  </Step>
</Steps>
