Giter VIP home page Giter VIP logo

maheshkrex / nestjs-kafka-microservice Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 1.0 292 KB

create two separate microservices that communicate via Kafka. One of these services will expose REST endpoints and produce messages to the Kafka broker. The other service will consume these messages and write them to a database or in-memory storage. Both services are maintained in a Monorepo.

JavaScript 11.44% Dockerfile 2.17% TypeScript 86.39%

nestjs-kafka-microservice's Introduction

Microservices on NestJS communicating via Kafka and experimenting on Producer / Consumer idempotency

The repo consists of two branches:

main branch:

The main task is to create two separate microservices that communicate via Kafka. One of these services exposes REST endpoints and produce messages to the Kafka broker. The other service consumes these messages and write them to an in-memory storage. Both services are maintained in a Monorepo.

idempotent-solution branch:

This branch has additional modules under each microservice trying to tackle idempotency at api-service(a.k.a producer) and database-service (a.k.a consumer) services.

Run Locally

Assuming kafka broker is available at this address, as configured at ./api-service/src/config/configuration.ts

 brokers: 'localhost:9092'

start services locally

  git clone https://github.com/maheshKRex/nestjs-kafka-microservice.git
  cd nestjs-kafka-microservice
  cd api-service
  npm install
  npm run start:dev

  cd ../database-service
  npm install
  npm run start:dev
  

Running Tests

To run tests, run the following command

  cd api-service
  npm run test:e2e

Examples

POST /user

curl --location 'http://localhost:3001/users' \
--header 'Content-Type: application/json' \
--data '{
    "id":"1",
    "name": "test user 1"
}'

GET /user/1

curl --location 'http://localhost:3001/users/1'
{
    "id": "1",
    "name": "test user 1"
}

Idempotent consumer

Approach

Added a way to track processed messages by a unique messageId. Each message needs to have a unique messageId assigned by the producing service, as a Kafka message header. When a new message is consumed the in-memory array is checked for the existence of this message Id. If present, then the message is a duplicate. The consumer updates its offsets to effectively mark the message as consumed to ensure it is not redelivered, and no further action takes place.

Example

git checkout idempotent-solution
./api-service/npm run start:dev
./database-service/npm run start:dev

create user with messageId 1111 POST /user

curl --location 'http://localhost:3001/users' \
--header 'Content-Type: application/json' \
--data '{
    "id":"1",
    "messageId":"1111",
    "name": "test user 1"
}'

retry the same curl command by sending the same value as the messageId 1111 POST /user

curl --location 'http://localhost:3001/users' \
--header 'Content-Type: application/json' \
--data '{
    "id":"1",
    "messageId":"1111",
    "name": "test user 1"
}'

check consumer console for detection of the duplicate message and the consumer commits the offset to avoid further duplications by other consumers.

Screenshots

https://ibb.co/GRbKXcZ

Optimizations

More Optimizations can be done on idempotent consumer solution explored here.

  • For instance, the logic of storing processed messageId and actuallty processing a message can be made atomic using transactions. There by avoid chances of failing to mark a message as processed or marking a message as processed and crashing the consumer, without really processing the message.

generally on the whole project:

  • can introduce Mono-repo management tools like nx comes with easy managemet tools: https://nx.dev/
  • shared settings between producer and consumer such as kafka broker addresses, topics can be moved to a shared library, to avoid duplicate code, there by not having to update settings at both services.

nestjs-kafka-microservice's People

Contributors

maheshkrex avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

mahesh2009

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.