{"id":14978618,"url":"https://github.com/gapur/nestjs-microservices","last_synced_at":"2025-10-28T11:31:45.584Z","repository":{"id":238361877,"uuid":"796395606","full_name":"Gapur/nestjs-microservices","owner":"Gapur","description":"🛰️ Building Microservices with NestJS, TCP and Typescript","archived":false,"fork":false,"pushed_at":"2024-06-12T19:13:42.000Z","size":310,"stargazers_count":9,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-29T01:41:05.916Z","etag":null,"topics":["microservice","microservices","monorepo","monorepository","nest","nestjs","nx","tcp","typescript"],"latest_commit_sha":null,"homepage":"https://medium.com/itnext/building-microservices-with-nestjs-tcp-and-typescript-dda33aad8b89","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Gapur.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-05T20:05:42.000Z","updated_at":"2024-06-28T13:41:11.000Z","dependencies_parsed_at":"2024-06-13T00:49:31.098Z","dependency_job_id":null,"html_url":"https://github.com/Gapur/nestjs-microservices","commit_stats":null,"previous_names":["gapur/nestjs-microservices"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gapur%2Fnestjs-microservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gapur%2Fnestjs-microservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gapur%2Fnestjs-microservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gapur%2Fnestjs-microservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Gapur","download_url":"https://codeload.github.com/Gapur/nestjs-microservices/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219859638,"owners_count":16556034,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["microservice","microservices","monorepo","monorepository","nest","nestjs","nx","tcp","typescript"],"created_at":"2024-09-24T13:58:02.408Z","updated_at":"2025-10-28T11:31:40.014Z","avatar_url":"https://github.com/Gapur.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Microservices\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://nestjs.com/\" target=\"blank\"\u003e\u003cimg src=\"https://nestjs.com/img/logo-small.svg\" width=\"200\" alt=\"Nest Logo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Building Microservices with NestJS, TCP and Typescript\n\nAs our projects get bigger and bigger, we need more and more advanced architecture. Therefore, as a software engineer, I would like to introduce you to the modern popular microservice architecture that follows the concept of SOA (Service Oriented Architecture).\n\nIn this article, I want to talk about the difference between monolithic and microservice architectures and show how to build them using `NestJS`, `TCP` and `Typescript`. Let’s first dive into what microservices are.\n\n## Getting Started\n\n1. Clone this repository\n```\ngit clone git@github.com:Gapur/nestjs-microservices.git\n```\n2. Install dependencies\n```\nnpm install\n```\n3. Launch app\n```\nnx serve api-gateway\nnx serve auth-microservice\n```\n\n## What are Microservices\n\nMicroservices are an architectural approach to software development in which software is composed of small, independent services that communicate through well-defined APIs. Each service supports a specific task or business goal and uses an API to communicate with other modules and services. This makes it easier to scale and faster to develop applications, enabling innovation and bringing new features to market faster.\n\nWhat are the key differences between monolithic and microservice architectures? If monolithic, then all functions and services in the application are combined and work as a single unit. But a microservice breaks down the underlying logic into different tasks or services, each of which can be developed, deployed separately and exposed via an API.\n\nFor a better understanding, we will develop a microservices project together in NestJS.\n\n## Setting Up the Project\n\nBefore we start, I would like to highlight two main aspects of our project:\n- auth-microservice — authentication service responsible for managing user permissions\n- API Gateway — a service between the client and the microservices that emits events from the HTTP API endpoint to the microservice\n\nIn short, when a user logs in with credentials through the `/api/login` endpoint, they are connected to the API Gateway. The API Gateway then sends and receives a message from the authentication microservice using a request-response style message pattern. This is roughly how our app will work.\n\nSince we’ll be building multiple services, it’s best to have a monorepo project, which is a single version-controlled code repository that includes various apps and libraries. Hence, we are going to use the [Nx](https://nx.dev) tool for mono-repository management, which allows you to build and scale web apps and services in a mono-repository.\n\nFirst, let’s just create a monorepo project with the following command:\n```sh\nnpx create-nx-workspace nestjs-microservices --preset=nest\n```\n\nSpecify the app name as `api-gateway`.\n\nNow let’s install the project dependencies by running the following commands:\n```sh\ncd nestjs-microservices\nnpm i @nestjs/microservices class-validator class-transformer\n```\n\n## Adding an Auth Module\n\nSince our project is created, nx has already created an `API Gateway` service application for us. Now we will create an auth module in our API Gateway app that is responsible for handling authentication related requests.\n\nWhen a user makes a request to our app, then the API Gateway receives and sends the request to the microservices. So they will use the same data type and it makes sense to create a shared library in our monorepo and avoid duplicating the same code all over the place with the following command:\n```sh\nnx g @nx/nest:lib shared\n```\n\nNow, let’s create a dto folder and add `create-user.dto.ts` file:\n```ts\n// shared/src/lib/dto/create-user.dto.ts\n\nimport { IsNotEmpty, IsString } from 'class-validator';\n\nexport class CreateUserDto {\n  @IsString()\n  @IsNotEmpty()\n  username: string;\n\n  @IsNotEmpty()\n  password: string;\n}\n```\n\nAlso we can add a path entry in the `tsconfig.base.json` and import them with absolute paths:\n\n```json\n{\n  ...\n  \"compilerOptions\": {\n    ...\n    \"paths\": {\n      \"@nestjs-microservices/shared\": [\"shared/src/index.ts\"]\n    }\n  },\n  ...\n}\n```\n\nNestJS transports messages between different microservice instances using the default TCP transport layer. NestJS provides a `ClientsModule` which exposes the static `register()` method that takes as an argument an array of objects describing the microservice transporters. Let’s add `auth.service.ts` and register `AUTH_MICROSERVICE` using the following lines of code:\n\n```ts\n// apps/api-gateway/src/auth/auth.module.ts\n\nimport { Module } from '@nestjs/common';\nimport { ClientsModule, Transport } from '@nestjs/microservices';\n\nimport { AuthController } from './auth.controller';\nimport { AuthService } from './auth.service';\n\n@Module({\n  imports: [\n    ClientsModule.register([\n      {\n        name: 'AUTH_MICROSERVICE',\n        transport: Transport.TCP,\n        options: {\n          host: 'localhost',\n          port: 3001,\n        },\n      },\n    ]),\n  ],\n  providers: [AuthService],\n  controllers: [AuthController],\n})\nexport class AuthModule {}\n```\n\nAbove, each transporter has a name property, an optional transport property (default is Transport.TCP), and an optional transporter-specific options property.\n\nOnce the module has been imported, we can inject a `ClientProxy` instance configured as specified using the AUTH_MICROSERVICE transporter parameters using the `@Inject()` decorator in the `auth.service.ts` as shown below:\n\n```ts\n// apps/api-gateway/src/auth/auth.service.ts\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { ClientProxy } from '@nestjs/microservices';\n\nimport { CreateUserDto, User } from '@nestjs-microservices/shared';\n\n@Injectable()\nexport class AuthService {\n  constructor(\n    @Inject('AUTH_MICROSERVICE') private readonly authClient: ClientProxy\n  ) {}\n\n  getUser(createUserDto: CreateUserDto) {\n    return this.authClient.send\u003cUser, CreateUserDto\u003e('get_user', createUserDto);\n  }\n\n  createUser(createUserDto: CreateUserDto) {\n    return this.authClient.send\u003cUser, CreateUserDto\u003e('create_user', createUserDto);\n  }\n}\n```\n\nAs shown above, we can send a message to the authentication microservice using the `get_user` or `create_user` patterns. We will use them when the user logs in or registers.\n\nThe send method is designed to call a microservice and returns an Observable as a response. This takes two arguments:\n- pattern — one defined in a @MessagePattern() decorator\n- payload — the message we want to transmit to the microservice\n\nLast, we’ll create an `AuthController` class with two API endpoints for login and signup:\n\n```ts\n// apps/api-gateway/src/auth/auth.controller.ts\n\nimport { Body, Controller, Post, BadRequestException } from '@nestjs/common';\nimport { lastValueFrom } from 'rxjs';\n\nimport { CreateUserDto, User } from '@nestjs-microservices/shared';\n\nimport { AuthService } from './auth.service';\n\n@Controller('auth')\nexport class AuthController {\n  constructor(private readonly authService: AuthService) {}\n\n  @Post('login')\n  async login(@Body() createUserDto: CreateUserDto) {\n    const user: User = await lastValueFrom(this.authService.getUser(createUserDto), {\n      defaultValue: undefined,\n    });\n    if (!user) {\n      throw new BadRequestException('Invalid credentials');\n    }\n\n    const isMatch = user.password === createUserDto.password;\n    if (!isMatch) {\n      throw new BadRequestException('Incorrect password');\n    }\n\n    console.log(`User ${user.username} successfully logged in.`);\n\n    return user;\n  }\n\n  @Post('signup')\n  async signup(@Body() createUserDto: CreateUserDto) {\n    const user: User = await lastValueFrom(this.authService.getUser(createUserDto), {\n      defaultValue: undefined,\n    });\n    if (user) {\n      throw new BadRequestException(\n        `Username ${createUserDto.username} already exists!`\n      );\n    }\n\n    return this.authService.createUser(createUserDto);\n  }\n}\n```\n\nAs mentioned earlier, the `getUser` and `createUser` auth client methods return an `Obserable`, which means you need to explicitly subscribe to it before the message is sent. But we can convert an Observable to a Promise using the `lastValueFrom` method imported from `rxjs`.\n\n## Creating an Auth Microservice\n\nNow we will create our first authentication microservice by running the following command:\n\n```sh\nnx g @nx/nest:app auth-microservice\n```\n\nLet’s update the bootstrap() function boilerplate code in the main.ts file of the auth-microservice app with the NestFactory.createMicroservice() method:\n\n```ts\n// apps/auth-microservice/src/main.ts\n\nimport { Logger } from '@nestjs/common';\nimport { NestFactory } from '@nestjs/core';\nimport { Transport, MicroserviceOptions } from '@nestjs/microservices';\n\nimport { AppModule } from './app/app.module';\n\nasync function bootstrap() {\n  const app = await NestFactory.createMicroservice\u003cMicroserviceOptions\u003e(\n    AppModule,\n    {\n      transport: Transport.TCP,\n      options: {\n        host: 'localhost',\n        port: 3001,\n      },\n    }\n  );\n\n  await app.listen();\n\n  Logger.log('🚀 Auth microservice is listening');\n}\n\nbootstrap();\n```\n\nThe `createMicroservice()` method of the NestFactory class creates an instance of a microservice.\n\nThen we’ll create a User entity in a shared library that we’ll use in the `UsersRepository` class to do things like storing user data and retrieving the user.\n\n```ts\n// shared/src/lib/entities/user.entity.ts\n\nexport class User {\n  id?: number;\n  username: string;\n  password: string;\n}\n```\n\nWe will not use any database and for brevity we will store the data in memory in this demo. Let’s create a simple `user.repository.ts` file with `UserRepository` class:\n\n```ts\n// apps/auth-microservice/src/app/user.repository.ts\n\nimport { Injectable } from '@nestjs/common';\n\nimport { CreateUserDto, User } from '@nestjs-microservices/shared';\n\n@Injectable()\nexport class UserRepository {\n  private users: User[] = [];\n\n  save(user: CreateUserDto): User {\n    const newUser = new User();\n    newUser.id = this.users.length + 1;\n    newUser.username = user.username;\n    newUser.password = user.password;\n    this.users.push(newUser);\n    return newUser;\n  }\n\n  findOne(username: string): User | undefined {\n    return this.users.find((user) =\u003e user.username === username);\n  }\n}\n```\n\nNow we are going to add `createUser()` and `getUser()` to create and find a user respectively using the `UserRepository` methods in the `app.service.ts`:\n\n```ts\n// apps/auth-microservice/src/app/app.service.ts\n\nimport { Injectable } from '@nestjs/common';\n\nimport { CreateUserDto, User } from '@nestjs-microservices/shared';\n\nimport { UserRepository } from './user.repository';\n\n@Injectable()\nexport class AppService {\n  constructor(private readonly userRepository: UserRepository) {}\n\n  createUser(newUser: CreateUserDto): User {\n    return this.userRepository.save(newUser);\n  }\n\n  getUser(username: string): User | undefined {\n    return this.userRepository.findOne(username);\n  }\n}\n```\n\nFinally, we’ll create message handler methods based on the request-response paradigm using the `@MessagePattern()` decorator, which is imported from the `@nestjs/microservices` package.\n\n```ts\n// apps/auth-microservice/src/app/app.controller.ts\n\n@Controller()\nexport class AppController {\n  constructor(private readonly appService: AppService) {}\n\n  @MessagePattern('get_user') // listens for the get_user message pattern\n  handleGetUser(user: CreateUserDto) {\n    return this.appService.getUser(user.username);\n  }\n\n  @MessagePattern('create_user') // listens for the create_user message pattern\n  handleCreateUser(newUser: CreateUserDto) {\n    return this.appService.createUser(newUser);\n  }\n}\n```\n\nIn the above code, the `handleGetUser()` message handler listens for messages matching the get_user message pattern. The message handler takes a single argument — the user as the `CreateUserDto` type passed from the client.\n\n## Running and Testing the Services\n\nTo test all services, we need to run the following commands individually on separate terminals:\n\n```sh\nnx serve api-gateway\nnx serve auth-microservice\n```\n\nTo test the app, we can use Postman or any other API client.\n\n# Conclusion\n\nThanks for reading — I hope you found this piece useful. Happy coding!\n\n## Article on Medium\n\n[Building Microservices with NestJS, TCP and Typescript](https://medium.com/itnext/building-microservices-with-nestjs-tcp-and-typescript-dda33aad8b89)\n\n## How to contribute?\n\n1. Fork this repo\n2. Clone your fork\n3. Code 🤓\n4. Test your changes\n5. Submit a PR!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgapur%2Fnestjs-microservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgapur%2Fnestjs-microservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgapur%2Fnestjs-microservices/lists"}