{"id":23721240,"url":"https://github.com/byndyusoft/nest-kafka","last_synced_at":"2025-09-03T21:31:36.671Z","repository":{"id":37808765,"uuid":"491467112","full_name":"Byndyusoft/nest-kafka","owner":"Byndyusoft","description":"Kafka for NestJS","archived":false,"fork":false,"pushed_at":"2024-10-30T02:44:58.000Z","size":524,"stargazers_count":23,"open_issues_count":24,"forks_count":4,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-10-30T05:10:11.530Z","etag":null,"topics":["kafka","nestjs","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Byndyusoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2022-05-12T10:28:51.000Z","updated_at":"2024-10-14T10:49:39.000Z","dependencies_parsed_at":"2023-12-03T09:26:53.129Z","dependency_job_id":"324610a7-8e16-43c3-8716-fb90f7815692","html_url":"https://github.com/Byndyusoft/nest-kafka","commit_stats":{"total_commits":25,"total_committers":6,"mean_commits":4.166666666666667,"dds":"0.19999999999999996","last_synced_commit":"bb1491d1e2d231b8445d3287d5cc25f3f5ff5cf4"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":"Byndyusoft/node-typescript-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2Fnest-kafka","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2Fnest-kafka/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2Fnest-kafka/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2Fnest-kafka/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Byndyusoft","download_url":"https://codeload.github.com/Byndyusoft/nest-kafka/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231918714,"owners_count":18445790,"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":["kafka","nestjs","nodejs","typescript"],"created_at":"2024-12-30T22:18:14.309Z","updated_at":"2024-12-30T22:18:16.054Z","avatar_url":"https://github.com/Byndyusoft.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nest-kafka\n\n[![npm@latest](https://img.shields.io/npm/v/@byndyusoft/nest-kafka/latest.svg)](https://www.npmjs.com/package/@byndyusoft/nest-kafka)\n[![test](https://github.com/Byndyusoft/nest-kafka/actions/workflows/test.yaml/badge.svg?branch=master)](https://github.com/Byndyusoft/nest-kafka/actions/workflows/test.yaml)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\nKafka for NestJS\n\n## Features\n\n- Multiple connections\n- Consumer and Producer with Schema Registry support (using [kafkajs](https://www.npmjs.com/package/kafkajs) and [@kafkajs/confluent-schema-registry](https://www.npmjs.com/package/@kafkajs/confluent-schema-registry) under the hood)\n- Integration with [nest-template](https://github.com/Byndyusoft/nest-template)\n- Consumer\n  - Subscribe topic is not static, you can pick it from config\n  - Process message in async context with [Tracing](https://www.npmjs.com/package/@byndyusoft/nest-opentracing) and [Logging](https://www.npmjs.com/package/@byndyusoft/nest-pino)\n  - String, JSON and Schema Registry decoders for key and value, headers decoder with array support\n  - [Dead letter queue](https://www.confluent.io/blog/error-handling-patterns-in-kafka/#pattern-2) pattern support with smart retry mechanism\n  - Support custom decoders and error handling patterns\n\n## Requirements\n\n- Node.js v14 LTS or later\n- Yarn\n\n## Install\n\n```bash\nyarn add @byndyusoft/nest-kafka @byndyusoft/class-validator-extended @byndyusoft/nest-opentracing @byndyusoft/nest-pino @kafkajs/confluent-schema-registry @nestjs/common @nestjs/microservices class-transformer class-validator kafkajs rxjs\n```\n\n## Usage\n\n### Init\n\n\u003cdetails\u003e\n\u003csummary\u003e1. Create \u003ccode\u003eKafkaConfigDto\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaClusterConfigDto,\n  KafkaConsumerConfigDto,\n  KafkaProducerConfigDto,\n  KafkaSchemaRegistryArgsConfigDto,\n} from \"@byndyusoft/nest-kafka\";\nimport { Type } from \"class-transformer\";\nimport { IsDefined, IsString, ValidateNested } from \"class-validator\";\n\nexport class KafkaConfigDto {\n  @Type(() =\u003e KafkaClusterConfigDto)\n  @IsDefined()\n  @ValidateNested()\n  public readonly cluster!: KafkaClusterConfigDto;\n\n  @Type(() =\u003e KafkaConsumerConfigDto)\n  @IsDefined()\n  @ValidateNested()\n  public readonly consumer!: KafkaConsumerConfigDto;\n\n  @Type(() =\u003e KafkaProducerConfigDto)\n  @IsDefined()\n  @ValidateNested()\n  public readonly producer!: KafkaProducerConfigDto;\n\n  @Type(() =\u003e KafkaSchemaRegistryArgsConfigDto)\n  @IsDefined()\n  @ValidateNested()\n  public readonly schemaRegistry!: KafkaSchemaRegistryArgsConfigDto;\n\n  @IsString()\n  public readonly topic!: string;\n\n  @IsString()\n  public readonly errorTopic!: string;\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e2. Add \u003ccode\u003eKafkaConfigDto\u003c/code\u003e into \u003ccode\u003eConfigDto\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport { Type } from \"class-transformer\";\nimport { IsDefined, ValidateNested } from \"class-validator\";\n\nimport { KafkaConfigDto } from \"./kafkaConfigDto\";\n\nexport class ConfigDto {\n  /// ...\n\n  @Type(() =\u003e KafkaConfigDto)\n  @IsDefined()\n  @ValidateNested()\n  public readonly kafka!: KafkaConfigDto;\n\n  /// ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3. Add env variables mapping\u003c/summary\u003e\n\n```typescript\nimport { Module } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"./dtos\";\n\n@Module({})\nexport class ConfigModule {\n  // ...\n\n  private static __loadConfig(): ConfigDto {\n    const plainConfig: ConfigDto = {\n      // ...\n      kafka: {\n        cluster: {\n          brokers: process.env.KAFKA_BROKERS as string,\n          saslMechanism: process.env.KAFKA_SASL_MECHANISM,\n          username: process.env.KAFKA_USERNAME,\n          password: process.env.KAFKA_PASSWORD,\n          ssl: process.env.KAFKA_SSL,\n          ca: process.env.KAFKA_CA,\n          connectionTimeout: process.env.KAFKA_CONNECTION_TIMEOUT, // default is 1 s.\n        },\n        consumer: {\n          groupId: process.env.KAFKA_CONSUMER_GROUP_ID as string,\n          allowAutoTopicCreation:\n            process.env.KAFKA_CONSUMER_ALLOW_AUTO_TOPIC_CREATION ?? true,\n          sessionTimeout: process.env.KAFKA_SESSION_TIMEOUT_MS ?? 30000,\n          heartbeatInterval: process.env.KAFKA_HEARTBEAT_INTERVAL_MS ?? 3000,\n        },\n        producer: {\n          allowAutoTopicCreation:\n            process.env.KAFKA_PRODUCER_ALLOW_AUTO_TOPIC_CREATION ?? true,\n        },\n        schemaRegistry: {\n          host: process.env.KAFKA_SCHEMA_REGISTRY_HOST as string,\n          username: process.env.KAFKA_SCHEMA_REGISTRY_USERNAME,\n          password: process.env.KAFKA_SCHEMA_REGISTRY_PASSWORD,\n        },\n        topic: process.env.KAFKA_TOPIC as string,\n        errorTopic: process.env.KAFKA_ERROR_TOPIC as string,\n      },\n      // ...\n    };\n\n    // ...\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e4. Import \u003ccode\u003eKafkaModule\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaClusterConfigDto,\n  KafkaConsumerConfigDto,\n  KafkaModule,\n  KafkaProducerConfigDto,\n  KafkaSchemaRegistryArgsConfigDto,\n} from \"@byndyusoft/nest-kafka\";\n\nimport { ConfigDto } from \"./config\";\n\n@Module({\n  imports: [\n    // Extra modules\n    // ...\n    KafkaModule.registerAsync({\n      inject: [ConfigDto],\n      useFactory: (config: ConfigDto) =\u003e ({\n        connections: [\n          {\n            cluster: KafkaClusterConfigDto.toRawConfig(config.kafka.cluster),\n            consumer: KafkaConsumerConfigDto.toRawConfig(config.kafka.consumer),\n            producer: KafkaProducerConfigDto.toRawConfig(config.kafka.producer),\n            schemaRegistry: {\n              args: KafkaSchemaRegistryArgsConfigDto.toRawConfig(\n                config.kafka.schemaRegistry,\n              ),\n            },\n          },\n        ],\n        topicPickerArgs: [config],\n      }),\n    }),\n    // ...\n  ],\n})\nexport class InfrastructureModule {\n  // ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e4.1. You can describe multiple connections (farther use \u003ccode\u003econnectionName\u003c/code\u003e parameter in some functions to specify your connection)\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaClusterConfigDto,\n  KafkaConsumerConfigDto,\n  KafkaModule,\n  KafkaProducerConfigDto,\n  KafkaSchemaRegistryArgsConfigDto,\n} from \"@byndyusoft/nest-kafka\";\n\nimport { ConfigDto } from \"./config\";\n\n@Module({\n  imports: [\n    // Extra modules\n    // ...\n    KafkaModule.registerAsync({\n      inject: [ConfigDto],\n      useFactory: (config: ConfigDto) =\u003e ({\n        connections: [\n          {\n            name: \"connection1\",\n            cluster: KafkaClusterConfigDto.toRawConfig(config.kafka1.cluster),\n            consumer: KafkaConsumerConfigDto.toRawConfig(\n              config.kafka1.consumer,\n            ),\n            producer: KafkaProducerConfigDto.toRawConfig(\n              config.kafka1.producer,\n            ),\n            schemaRegistry: {\n              args: KafkaSchemaRegistryArgsConfigDto.toRawConfig(\n                config.kafka1.schemaRegistry,\n              ),\n            },\n          },\n          {\n            name: \"connection2\",\n            cluster: KafkaClusterConfigDto.toRawConfig(config.kafka2.cluster),\n            consumer: KafkaConsumerConfigDto.toRawConfig(\n              config.kafka2.consumer,\n            ),\n            producer: KafkaProducerConfigDto.toRawConfig(\n              config.kafka2.producer,\n            ),\n            schemaRegistry: {\n              args: KafkaSchemaRegistryArgsConfigDto.toRawConfig(\n                config.kafka2.schemaRegistry,\n              ),\n            },\n          },\n        ],\n        topicPickerArgs: [config],\n      }),\n    }),\n    // ...\n  ],\n})\nexport class InfrastructureModule {\n  // ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e4.2. If you want, you can not create \u003ccode\u003econsumer\u003c/code\u003e, \u003ccode\u003eproducer\u003c/code\u003e or \u003ccode\u003eschemaRegistry\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaClusterConfigDto,\n  KafkaConsumerConfigDto,\n  KafkaModule,\n  KafkaProducerConfigDto,\n  KafkaSchemaRegistryArgsConfigDto,\n} from \"@byndyusoft/nest-kafka\";\n\nimport { ConfigDto } from \"./config\";\n\n@Module({\n  imports: [\n    // Extra modules\n    // ...\n    KafkaModule.registerAsync({\n      inject: [ConfigDto],\n      useFactory: (config: ConfigDto) =\u003e ({\n        connections: [\n          {\n            cluster: KafkaClusterConfigDto.toRawConfig(config.kafka.cluster),\n            consumer: KafkaConsumerConfigDto.toRawConfig(config.kafka.consumer),\n          },\n        ],\n        topicPickerArgs: [config],\n      }),\n    }),\n    // ...\n  ],\n})\nexport class InfrastructureModule {\n  // ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e5. Connect microservice to start consuming messages\u003c/summary\u003e\n\n```typescript\nimport { KafkaConsumer, KafkaRetryConsumer } from \"@byndyusoft/nest-kafka\";\nimport { MicroserviceOptions } from \"@nestjs/microservices\";\n\nasync function bootstrap(): Promise\u003cvoid\u003e {\n  // ...\n\n  app.connectMicroservice\u003cMicroserviceOptions\u003e({\n    strategy: app.get(KafkaConsumer),\n  });\n\n  // you can optionally connect retry consumer\n  app.connectMicroservice\u003cMicroserviceOptions\u003e({\n    strategy: app.get(KafkaRetryConsumer),\n  });\n\n  // Put `app.listen(...)` before `app.startAllMicroservice()`\n  await app.listen(...)\n\n  await app.startAllMicroservices();\n\n  // ...\n}\n\n// ...\n```\n\n\u003c/details\u003e\n\n### Consuming Messages\n\n\u003e [!IMPORTANT]\n\u003e Put `app.startAllMicroservices()` after your `app.listen(...)`\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e1. Create controller and use \u003ccode\u003eKafkaConsumerEventPattern\u003c/code\u003e to describe consumer\u003c/summary\u003e\n\n```typescript\nimport {\n  IKafkaConsumerPayload,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller } from \"@nestjs/common\";\nimport { Payload } from \"@nestjs/microservices\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  public async onMessage(\n    @Payload() payload: IKafkaConsumerPayload,\n  ): Promise\u003cvoid\u003e {\n    // ...\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e2. Decode payload\u003c/summary\u003e\n\n```typescript\nimport {\n  IKafkaConsumerPayload,\n  KafkaConsumerEventPattern,\n  KafkaConsumerPayloadDecoder,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseInterceptors } from \"@nestjs/common\";\nimport { Payload } from \"@nestjs/microservices\";\n\nimport { ConfigDto } from \"~/src\";\nimport { UserDto } from \"ᐸDtosᐳ\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseInterceptors(\n    new KafkaConsumerPayloadDecoder({\n      key: \"string\",\n      value: \"json\",\n      headers: \"string\",\n    }),\n  )\n  public async onMessage(\n    @Payload() payload: IKafkaConsumerPayload\u003cstring, UserDto\u003e,\n  ): Promise\u003cvoid\u003e {\n    // ...\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e2.1. You can use param decorators to get key, value or headers\u003c/summary\u003e\n\n```typescript\nimport {\n  IKafkaConsumerPayloadHeaders,\n  KafkaConsumerEventPattern,\n  KafkaConsumerPayloadDecoder,\n  KafkaHeaders,\n  KafkaKey,\n  KafkaValue,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseInterceptors } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\nimport { UserDto } from \"ᐸDtosᐳ\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseInterceptors(\n    new KafkaConsumerPayloadDecoder({\n      key: \"string\",\n      value: \"json\",\n      headers: \"string\",\n    }),\n  )\n  public async onMessage(\n    @KafkaKey() key: string,\n    @KafkaValue() value: UserDto,\n    @KafkaHeaders() headers: IKafkaConsumerPayloadHeaders,\n  ): Promise\u003cvoid\u003e {\n    // ...\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3. Always use some exception filter for correct error handling\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaConsumerBaseExceptionFilter,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseFilters } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseFilters(/* ... */)\n  public async onMessage(): Promise\u003cvoid\u003e {\n    throw new Error(\"some error\");\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3.1. Use \u003ccode\u003eKafkaConsumerBaseExceptionFilter\u003c/code\u003e if you prefer \u003ca href=\"https://www.confluent.io/blog/error-handling-patterns-in-kafka/#pattern-1\"\u003eStop on error\u003c/a\u003e pattern\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaConsumerBaseExceptionFilter,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseFilters } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseFilters(new KafkaConsumerBaseExceptionFilter())\n  public async onMessage(): Promise\u003cvoid\u003e {\n    throw new Error(\"some error\");\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3.2. Use \u003ccode\u003eKafkaConsumerErrorTopicExceptionFilter\u003c/code\u003e if you prefer \u003ca href=\"https://www.confluent.io/blog/error-handling-patterns-in-kafka/#pattern-2\"\u003eDead letter queue\u003c/a\u003e pattern\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaConsumerErrorTopicExceptionFilter,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseFilters } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseFilters(\n    new KafkaConsumerErrorTopicExceptionFilter({\n      errorTopicPicker: (config: ConfigDto) =\u003e config.kafka.errorTopic,\n    }),\n  )\n  public async onMessage(): Promise\u003cvoid\u003e {\n    throw new Error(\"some error\");\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3.3. \u003ccode\u003eKafkaConsumerErrorTopicExceptionFilter\u003c/code\u003e also support retry topic for retriable errors\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaConsumerErrorTopicExceptionFilter,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseFilters } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersConsumer {\n  @KafkaConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.topic,\n    fromBeginning: true,\n  })\n  @UseFilters(\n    new KafkaConsumerErrorTopicExceptionFilter({\n      retryTopicPicker: (config: ConfigDto) =\u003e config.kafka.retryTopic,\n      errorTopicPicker: (config: ConfigDto) =\u003e config.kafka.errorTopic,\n    }),\n  )\n  public async onMessage(): Promise\u003cvoid\u003e {\n    throw new Error(\"some error\");\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e3.4. Use retry consumer to consume messages from retry topic\u003c/summary\u003e\n\n```typescript\nimport {\n  KafkaConsumerErrorTopicExceptionFilter,\n  KafkaConsumerEventPattern,\n} from \"@byndyusoft/nest-kafka\";\nimport { Controller, UseFilters } from \"@nestjs/common\";\n\nimport { ConfigDto } from \"~/src\";\n\n@Controller()\nexport class UsersRetryConsumer {\n  @KafkaRetryConsumerEventPattern({\n    topicPicker: (config: ConfigDto) =\u003e config.kafka.retryTopic,\n    fromBeginning: true,\n  })\n  @UseFilters(\n    new KafkaConsumerErrorTopicExceptionFilter({\n      retryTopicPicker: false,\n      errorTopicPicker: (config: ConfigDto) =\u003e config.kafka.errorTopic,\n      resendHeadersPrefix: \"retry\",\n    }),\n  )\n  public async onMessage(): Promise\u003cvoid\u003e {\n    throw new Error(\"some error\");\n  }\n}\n```\n\nRun retry consumer, e.g by HTTP:\n\n```typescript\nimport { ApiTags } from \"@byndyusoft/nest-swagger\";\nimport { Body, Controller, HttpCode, HttpStatus, Post } from \"@nestjs/common\";\n\nimport { ApiCommonResponses } from \"../infrastructure\";\n\nimport { RunDeliveryAppointmentsRetryConsumerOnceBodyDto } from \"./dtos\";\nimport { RunDeliveryAppointmentsRetryConsumerOnceUseCase } from \"./useCases\";\n\n@ApiTags(\"Users\")\n@Controller({\n  path: \"/users/retry\",\n  version: \"1\",\n})\nexport class UsersRetryController {\n  public constructor(\n    private readonly config: ConfigDto,\n    private readonly kafkaRetryConsumer: KafkaRetryConsumer,\n  ) {}\n\n  @ApiCommonResponses(HttpStatus.BAD_REQUEST)\n  @HttpCode(HttpStatus.NO_CONTENT)\n  @Post(\"/runRetryConsumerOnce\")\n  public runDeliveryAppointmentsRetryConsumerOnce(): Promise\u003cvoid\u003e {\n    await this.kafkaRetryConsumer.runOnce({\n      topic: config.kafka.retryTopic,\n      messagesCount: 1,\n    });\n  }\n}\n```\n\n\u003c/details\u003e\n\n### Producing Messages\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e1. Inject \u003ccode\u003eKafkaProducer\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport { InjectKafkaProducer, KafkaProducer } from \"@byndyusoft/nest-kafka\";\nimport { Injectable } from \"@nestjs/common\";\n\n@Injectable()\nexport class UsersService {\n  public constructor(\n    @InjectKafkaProducer()\n    private readonly __kafkaProducer: KafkaProducer,\n  ) {}\n}\n```\n\n\u003c/details\u003e\n\n### Schema Registry\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e1. Inject \u003ccode\u003eKafkaSchemaRegistry\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nimport {\n  InjectKafkaSchemaRegistry,\n  KafkaSchemaRegistry,\n} from \"@byndyusoft/nest-kafka\";\nimport { Injectable } from \"@nestjs/common\";\n\n@Injectable()\nexport class UsersService {\n  public constructor(\n    @InjectKafkaSchemaRegistry()\n    private readonly __kafkaSchemaRegistry: KafkaSchemaRegistry,\n  ) {}\n}\n```\n\n\u003c/details\u003e\n\n## Maintainers\n\n- [@Byndyusoft/owners](https://github.com/orgs/Byndyusoft/teams/owners) \u003c\u003cgithub.maintain@byndyusoft.com\u003e\u003e\n- [@Byndyusoft/team](https://github.com/orgs/Byndyusoft/teams/team)\n- [@KillWolfVlad](https://github.com/KillWolfVlad)\n\n## License\n\nThis repository is released under version 2.0 of the\n[Apache License](https://www.apache.org/licenses/LICENSE-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyndyusoft%2Fnest-kafka","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyndyusoft%2Fnest-kafka","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyndyusoft%2Fnest-kafka/lists"}