@venizia/ignis-docs 0.2.0 → 0.2.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +22 -11
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +26 -2
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +6 -2
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +182 -93
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +107 -322
- package/content/extensions/components/authentication/api.md +454 -603
- package/content/extensions/components/authentication/errors.md +121 -498
- package/content/extensions/components/authentication/index.md +88 -801
- package/content/extensions/components/authentication/usage.md +207 -956
- package/content/extensions/components/authorization/api.md +736 -656
- package/content/extensions/components/authorization/errors.md +168 -206
- package/content/extensions/components/authorization/index.md +82 -797
- package/content/extensions/components/authorization/usage.md +194 -527
- package/content/extensions/components/health-check.md +71 -243
- package/content/extensions/components/mail/api.md +504 -287
- package/content/extensions/components/mail/errors.md +73 -61
- package/content/extensions/components/mail/index.md +96 -467
- package/content/extensions/components/mail/usage.md +130 -172
- package/content/extensions/components/request-tracker.md +66 -173
- package/content/extensions/components/socket-io/api.md +195 -13
- package/content/extensions/components/socket-io/errors.md +3 -3
- package/content/extensions/components/socket-io/index.md +50 -337
- package/content/extensions/components/socket-io/usage.md +143 -26
- package/content/extensions/components/static-asset/api.md +410 -142
- package/content/extensions/components/static-asset/errors.md +110 -53
- package/content/extensions/components/static-asset/index.md +79 -608
- package/content/extensions/components/static-asset/usage.md +180 -300
- package/content/extensions/components/websocket/api.md +275 -399
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +74 -407
- package/content/extensions/components/websocket/usage.md +110 -341
- package/content/extensions/helpers/cron/index.md +51 -160
- package/content/extensions/helpers/crypto/index.md +62 -483
- package/content/extensions/helpers/crypto/reference.md +456 -0
- package/content/extensions/helpers/env/index.md +60 -178
- package/content/extensions/helpers/error/index.md +221 -207
- package/content/extensions/helpers/inversion/index.md +65 -556
- package/content/extensions/helpers/inversion/reference.md +522 -0
- package/content/extensions/helpers/kafka/admin.md +20 -1
- package/content/extensions/helpers/kafka/compile-binary.md +41 -35
- package/content/extensions/helpers/kafka/consumer.md +54 -20
- package/content/extensions/helpers/kafka/examples.md +21 -16
- package/content/extensions/helpers/kafka/index.md +80 -610
- package/content/extensions/helpers/kafka/producer.md +134 -5
- package/content/extensions/helpers/kafka/schema-registry.md +45 -70
- package/content/extensions/helpers/logger/hf-logger.md +193 -0
- package/content/extensions/helpers/logger/index.md +64 -563
- package/content/extensions/helpers/logger/pino.md +85 -0
- package/content/extensions/helpers/logger/reference.md +746 -0
- package/content/extensions/helpers/network/api.md +241 -195
- package/content/extensions/helpers/network/index.md +72 -530
- package/content/extensions/helpers/queue/index.md +72 -900
- package/content/extensions/helpers/queue/reference.md +467 -0
- package/content/extensions/helpers/redis/index.md +73 -645
- package/content/extensions/helpers/redis/reference.md +727 -0
- package/content/extensions/helpers/secrets/index.md +66 -0
- package/content/extensions/helpers/socket-io/api.md +305 -203
- package/content/extensions/helpers/socket-io/index.md +66 -432
- package/content/extensions/helpers/storage/api.md +564 -462
- package/content/extensions/helpers/storage/index.md +77 -573
- package/content/extensions/helpers/types/index.md +66 -499
- package/content/extensions/helpers/types/reference.md +650 -0
- package/content/extensions/helpers/uid/index.md +58 -227
- package/content/extensions/helpers/websocket/api.md +329 -216
- package/content/extensions/helpers/websocket/index.md +65 -503
- package/content/extensions/helpers/worker-thread/index.md +58 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/search-typesense.md +3 -3
- package/content/guides/core-concepts/persistent/transactions.md +1 -1
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/migrations/redis-helpers-migration.md +1 -1
- package/content/guides/migrations/unified-connectors-migration.md +2 -2
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/references/base/application.md +1 -1
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/datasources-reference.md +599 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +17 -39
- package/content/references/base/filter-system/application-usage.md +69 -121
- package/content/references/base/filter-system/array-operators.md +12 -0
- package/content/references/base/filter-system/comparison-operators.md +12 -0
- package/content/references/base/filter-system/default-filter.md +136 -348
- package/content/references/base/filter-system/fields-order-pagination.md +38 -16
- package/content/references/base/filter-system/index.md +106 -257
- package/content/references/base/filter-system/json-filtering.md +12 -2
- package/content/references/base/filter-system/list-operators.md +16 -2
- package/content/references/base/filter-system/logical-operators.md +13 -0
- package/content/references/base/filter-system/null-operators.md +13 -0
- package/content/references/base/filter-system/pattern-matching.md +12 -0
- package/content/references/base/filter-system/quick-reference.md +11 -2
- package/content/references/base/filter-system/range-operators.md +12 -0
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +156 -233
- package/content/references/base/middlewares.md +35 -21
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +80 -1452
- package/content/references/base/repositories/advanced.md +156 -192
- package/content/references/base/repositories/index.md +77 -650
- package/content/references/base/repositories/mixins.md +22 -18
- package/content/references/base/repositories/relations.md +123 -171
- package/content/references/base/repositories/soft-deletable.md +58 -56
- package/content/references/base/secrets.md +263 -0
- package/content/references/base/services.md +2 -2
- package/content/references/configuration/environment-variables.md +48 -4
- package/content/references/configuration/index.md +49 -31
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/index.md +1 -1
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +29 -62
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +57 -218
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/package.json +8 -8
|
@@ -1,646 +1,116 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Apache Kafka
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
The Kafka module provides four helper classes built on a shared `BaseKafkaHelper` base:
|
|
8
|
-
|
|
9
|
-
| Class | Wraps | Use Case |
|
|
10
|
-
|-------|-------|----------|
|
|
11
|
-
| `KafkaProducerHelper` | `Producer` | Publish messages, transactions |
|
|
12
|
-
| `KafkaConsumerHelper` | `Consumer` | Consume messages with consumer groups, lag monitoring |
|
|
13
|
-
| `KafkaAdminHelper` | `Admin` | Manage topics, partitions, groups, ACLs, configs |
|
|
14
|
-
| `KafkaSchemaRegistryHelper` | `ConfluentSchemaRegistry` | Schema validation and auto ser/deser |
|
|
15
|
-
|
|
16
|
-
All helpers (except schema registry) extend `BaseKafkaHelper` which provides:
|
|
17
|
-
|
|
18
|
-
- **Scoped logging** via `BaseHelper` (Winston with daily rotation)
|
|
19
|
-
- **Health tracking** -- per-broker connection tracking via `isHealthy()`, `isReady()`, `getHealthStatus()`, `getConnectedBrokerCount()`
|
|
20
|
-
- **Broker event callbacks** -- `onBrokerConnect`, `onBrokerDisconnect`
|
|
21
|
-
- **Broker failure tracking** -- automatic `configureBrokerFailed()` sets status to `'disconnected'` only when all brokers are gone
|
|
22
|
-
- **Graceful shutdown** -- timeout-based with force fallback
|
|
23
|
-
- **Sensible defaults** via `KafkaDefaults` constants
|
|
24
|
-
- **Factory pattern** via `newInstance()` static method
|
|
25
|
-
|
|
26
|
-
Use `getProducer()`, `getConsumer()`, or `getAdmin()` to access the full underlying `@platformatic/kafka` API directly.
|
|
27
|
-
|
|
28
|
-
### Import Path
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
// Helpers & constants (via subpath export)
|
|
32
|
-
import {
|
|
33
|
-
KafkaProducerHelper,
|
|
34
|
-
KafkaConsumerHelper,
|
|
35
|
-
KafkaAdminHelper,
|
|
36
|
-
KafkaSchemaRegistryHelper,
|
|
37
|
-
BaseKafkaHelper,
|
|
38
|
-
KafkaDefaults,
|
|
39
|
-
KafkaAcks,
|
|
40
|
-
KafkaGroupProtocol,
|
|
41
|
-
KafkaHealthStatuses,
|
|
42
|
-
KafkaClientEvents,
|
|
43
|
-
} from '@venizia/ignis-helpers/kafka';
|
|
44
|
-
|
|
45
|
-
// Types
|
|
46
|
-
import type {
|
|
47
|
-
IKafkaConnectionOptions,
|
|
48
|
-
IKafkaProducerOptions,
|
|
49
|
-
IKafkaConsumerOptions,
|
|
50
|
-
IKafkaAdminOptions,
|
|
51
|
-
IKafkaConsumeStartOptions,
|
|
52
|
-
IKafkaSchemaRegistryOptions,
|
|
53
|
-
IKafkaTransactionContext,
|
|
54
|
-
IKafkaBaseOptions,
|
|
55
|
-
TKafkaAcks,
|
|
56
|
-
TKafkaGroupProtocol,
|
|
57
|
-
TKafkaHealthStatus,
|
|
58
|
-
TKafkaBrokerEventCallback,
|
|
59
|
-
TKafkaMessageCallback,
|
|
60
|
-
TKafkaMessageDoneCallback,
|
|
61
|
-
TKafkaMessageErrorCallback,
|
|
62
|
-
TKafkaGroupJoinCallback,
|
|
63
|
-
TKafkaGroupLeaveCallback,
|
|
64
|
-
TKafkaGroupRebalanceCallback,
|
|
65
|
-
TKafkaHeartbeatErrorCallback,
|
|
66
|
-
TKafkaLagCallback,
|
|
67
|
-
TKafkaLagErrorCallback,
|
|
68
|
-
TKafkaTransactionCallback,
|
|
69
|
-
} from '@venizia/ignis-helpers/kafka';
|
|
70
|
-
|
|
71
|
-
// @platformatic/kafka (direct usage)
|
|
72
|
-
import {
|
|
73
|
-
Producer, Consumer, Admin, MessagesStream,
|
|
74
|
-
stringSerializers, stringDeserializers,
|
|
75
|
-
stringSerializer, stringDeserializer,
|
|
76
|
-
jsonSerializer, jsonDeserializer,
|
|
77
|
-
serializersFrom, deserializersFrom,
|
|
78
|
-
} from '@platformatic/kafka';
|
|
79
|
-
|
|
80
|
-
import type {
|
|
81
|
-
Message, MessageToProduce,
|
|
82
|
-
SendOptions, ConsumeOptions,
|
|
83
|
-
Serializers, Deserializers,
|
|
84
|
-
SASLOptions, ConnectionOptions,
|
|
85
|
-
} from '@platformatic/kafka';
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
> [!NOTE]
|
|
89
|
-
> Kafka helpers are **not** re-exported from the main `@venizia/ignis-helpers` entry point. You must use the `@venizia/ignis-helpers/kafka` subpath import. This keeps the optional `@platformatic/kafka` peer dependency isolated for tree-shaking.
|
|
90
|
-
|
|
91
|
-
> [!WARNING]
|
|
92
|
-
> Compiling an application that uses these helpers with `bun build --compile` produces a binary that dies on startup with `ENOENT: /$bunfs/dist/native.wasm`. The build must register `platformaticWasmPlugin` from `@venizia/ignis-helpers/kafka` -- see [Compiling to a Single Binary](./compile-binary.md).
|
|
93
|
-
|
|
94
|
-
### Installation
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
bun add @platformatic/kafka
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Architecture
|
|
101
|
-
|
|
102
|
-
### Class Hierarchy
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
BaseHelper (scoped logging, identifier)
|
|
106
|
-
+-- BaseKafkaHelper<TClient> (health tracking, broker events, graceful shutdown)
|
|
107
|
-
| +-- KafkaProducerHelper<K,V,HK,HV>
|
|
108
|
-
| +-- KafkaConsumerHelper<K,V,HK,HV>
|
|
109
|
-
| +-- KafkaAdminHelper
|
|
110
|
-
|
|
|
111
|
-
+-- KafkaSchemaRegistryHelper<K,V,HK,HV> (no broker connection)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### BaseKafkaHelper
|
|
115
|
-
|
|
116
|
-
All Kafka helpers (except schema registry) extend `BaseKafkaHelper<TClient>`, which provides:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
abstract class BaseKafkaHelper<TClient extends Base<BaseOptions>> extends BaseHelper {
|
|
120
|
-
// Health
|
|
121
|
-
isHealthy(): boolean; // true when at least one broker is connected
|
|
122
|
-
isReady(): boolean; // healthStatus === 'connected' (consumer overrides: + isActive())
|
|
123
|
-
getHealthStatus(): TKafkaHealthStatus; // 'connected' | 'disconnected' | 'unknown'
|
|
124
|
-
getConnectedBrokerCount(): number; // number of currently connected brokers
|
|
125
|
-
|
|
126
|
-
// Shutdown (used by subclasses)
|
|
127
|
-
protected closeClient(): Promise<void>;
|
|
128
|
-
protected gracefulCloseClient(): Promise<void>; // races closeClient vs shutdownTimeout
|
|
129
|
-
protected resetHealthState(): void; // clears broker tracking + sets 'disconnected'
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Health tracking uses a **per-broker connection set** (`host:port` keys). A single idle broker disconnect does not make the client unhealthy -- only when **all** brokers are disconnected does `isHealthy()` return `false`.
|
|
134
|
-
|
|
135
|
-
Health status transitions automatically via broker events:
|
|
136
|
-
- `client:broker:connect` -> adds broker, sets `healthStatus` to `'connected'`
|
|
137
|
-
- `client:broker:disconnect` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
|
|
138
|
-
- `client:broker:failed` -> removes broker, sets `healthStatus` to `'disconnected'` only when all brokers are gone
|
|
139
|
-
- `close()` -> clears all brokers, sets `healthStatus` to `'disconnected'`
|
|
140
|
-
|
|
141
|
-
## Connection Options
|
|
142
|
-
|
|
143
|
-
All three helpers share a common base interface `IKafkaConnectionOptions` which extends `@platformatic/kafka`'s `ConnectionOptions`.
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
interface IKafkaConnectionOptions extends ConnectionOptions {
|
|
147
|
-
bootstrapBrokers: string[];
|
|
148
|
-
clientId: string;
|
|
149
|
-
retries?: number; // Default: 3
|
|
150
|
-
retryDelay?: number; // Default: 1000ms
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Full Options Table
|
|
155
|
-
|
|
156
|
-
| Option | Type | Default | Description |
|
|
157
|
-
|--------|------|---------|-------------|
|
|
158
|
-
| `bootstrapBrokers` | `string[]` | -- | Kafka broker addresses (`host:port`). **Required** |
|
|
159
|
-
| `clientId` | `string` | -- | Unique client identifier. **Required** |
|
|
160
|
-
| `retries` | `number` | `3` | Number of connection retries before failing |
|
|
161
|
-
| `retryDelay` | `number` | `1000` | Delay between retries in milliseconds |
|
|
162
|
-
| `sasl` | `SASLOptions` | -- | SASL authentication configuration |
|
|
163
|
-
| `tls` | `TLSConnectionOptions` | -- | TLS/SSL connection options |
|
|
164
|
-
| `ssl` | `TLSConnectionOptions` | -- | Alias for `tls` |
|
|
165
|
-
| `connectTimeout` | `number` | -- | TCP connection timeout in milliseconds |
|
|
166
|
-
| `requestTimeout` | `number` | -- | Kafka request timeout in milliseconds |
|
|
167
|
-
|
|
168
|
-
### Shared Helper Options
|
|
169
|
-
|
|
170
|
-
These options are available on all three helpers (`IKafkaProducerOptions`, `IKafkaConsumerOptions`, `IKafkaAdminOptions`):
|
|
171
|
-
|
|
172
|
-
| Option | Type | Default | Description |
|
|
173
|
-
|--------|------|---------|-------------|
|
|
174
|
-
| `identifier` | `string` | `'kafka-{type}'` | Scoped logging identifier |
|
|
175
|
-
| `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
|
|
176
|
-
| `onBrokerConnect` | `TKafkaBrokerEventCallback` | -- | Called when broker connects |
|
|
177
|
-
| `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | -- | Called when broker disconnects |
|
|
178
|
-
|
|
179
|
-
### SASL Authentication
|
|
180
|
-
|
|
181
|
-
`@platformatic/kafka` supports five SASL mechanisms:
|
|
1
|
+
---
|
|
2
|
+
title: Kafka
|
|
3
|
+
description: Apache Kafka producer, consumer, admin, and schema registry helpers built on a pure TypeScript client
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
182
6
|
|
|
183
|
-
|
|
184
|
-
|-----------|----------|
|
|
185
|
-
| `PLAIN` | Simple username/password (use with TLS in production) |
|
|
186
|
-
| `SCRAM-SHA-256` | Challenge-response, password never sent in plaintext |
|
|
187
|
-
| `SCRAM-SHA-512` | Same as SHA-256 with stronger hash |
|
|
188
|
-
| `OAUTHBEARER` | Token-based (Azure Event Hubs, Confluent Cloud) |
|
|
189
|
-
| `GSSAPI` | Kerberos authentication |
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
interface SASLOptions {
|
|
193
|
-
mechanism: 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512' | 'OAUTHBEARER' | 'GSSAPI';
|
|
194
|
-
username?: string | CredentialProvider;
|
|
195
|
-
password?: string | CredentialProvider;
|
|
196
|
-
token?: string | CredentialProvider;
|
|
197
|
-
oauthBearerExtensions?: Record<string, string> | CredentialProvider<Record<string, string>>;
|
|
198
|
-
authenticate?: SASLCustomAuthenticator;
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
#### SCRAM-SHA-512 Example
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
const helper = KafkaConsumerHelper.newInstance({
|
|
206
|
-
bootstrapBrokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],
|
|
207
|
-
clientId: 'my-consumer',
|
|
208
|
-
groupId: 'my-group',
|
|
209
|
-
sasl: {
|
|
210
|
-
mechanism: 'SCRAM-SHA-512',
|
|
211
|
-
username: 'kafka-user',
|
|
212
|
-
password: 'kafka-password',
|
|
213
|
-
},
|
|
214
|
-
connectTimeout: 30_000,
|
|
215
|
-
requestTimeout: 30_000,
|
|
216
|
-
onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}:${broker.port}`),
|
|
217
|
-
});
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
#### OAUTHBEARER Example
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
const helper = KafkaProducerHelper.newInstance({
|
|
224
|
-
bootstrapBrokers: ['pkc-xxxxx.us-west-2.aws.confluent.cloud:9092'],
|
|
225
|
-
clientId: 'my-producer',
|
|
226
|
-
sasl: {
|
|
227
|
-
mechanism: 'OAUTHBEARER',
|
|
228
|
-
token: async () => {
|
|
229
|
-
const response = await fetch('https://auth.example.com/token', { method: 'POST' });
|
|
230
|
-
const { access_token } = await response.json();
|
|
231
|
-
return access_token;
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
tls: true,
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
#### TLS Without SASL
|
|
239
|
-
|
|
240
|
-
```typescript
|
|
241
|
-
const helper = KafkaProducerHelper.newInstance({
|
|
242
|
-
bootstrapBrokers: ['broker:9093'],
|
|
243
|
-
clientId: 'my-producer',
|
|
244
|
-
tls: {
|
|
245
|
-
ca: fs.readFileSync('/path/to/ca.pem'),
|
|
246
|
-
cert: fs.readFileSync('/path/to/client-cert.pem'),
|
|
247
|
-
key: fs.readFileSync('/path/to/client-key.pem'),
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Serialization & Deserialization
|
|
253
|
-
|
|
254
|
-
`@platformatic/kafka`'s default wire format is `Buffer`. The helpers default generic types to `string` (matching common usage), but you must provide serializers/deserializers explicitly.
|
|
255
|
-
|
|
256
|
-
### Built-in Serializers
|
|
257
|
-
|
|
258
|
-
| Export | Type | Description |
|
|
259
|
-
|--------|------|-------------|
|
|
260
|
-
| `stringSerializer` | `Serializer<string>` | `string -> Buffer` (UTF-8) |
|
|
261
|
-
| `stringDeserializer` | `Deserializer<string>` | `Buffer -> string` (UTF-8) |
|
|
262
|
-
| `jsonSerializer` | `Serializer<T>` | `object -> Buffer` (JSON.stringify + UTF-8) |
|
|
263
|
-
| `jsonDeserializer` | `Deserializer<T>` | `Buffer -> object` (UTF-8 + JSON.parse) |
|
|
264
|
-
| `stringSerializers` | `Serializers<string, string, string, string>` | All four positions as string |
|
|
265
|
-
| `stringDeserializers` | `Deserializers<string, string, string, string>` | All four positions as string |
|
|
7
|
+
# Kafka
|
|
266
8
|
|
|
267
|
-
|
|
9
|
+
The Kafka helpers wrap `@platformatic/kafka` with four scoped classes - producer, consumer, admin, and schema registry - that add health tracking, graceful shutdown, and IGNIS-style scoped logging on top of the underlying client.
|
|
268
10
|
|
|
269
|
-
|
|
270
|
-
|--------|-----------|-------------|
|
|
271
|
-
| `serializersFrom(s)` | `<T>(s: Serializer<T>) => Serializers<T, T, T, T>` | Create full serializers from a single serializer |
|
|
272
|
-
| `deserializersFrom(d)` | `<T>(d: Deserializer<T>) => Deserializers<T, T, T, T>` | Create full deserializers from a single deserializer |
|
|
11
|
+
## In one example
|
|
273
12
|
|
|
274
|
-
|
|
13
|
+
The smallest real use: create a producer, send a message through the underlying client, and close it.
|
|
275
14
|
|
|
276
15
|
```typescript
|
|
277
|
-
import {
|
|
16
|
+
import { KafkaProducerHelper } from '@venizia/ignis-helpers/kafka';
|
|
17
|
+
import { stringSerializers } from '@platformatic/kafka';
|
|
278
18
|
|
|
279
19
|
const producer = KafkaProducerHelper.newInstance({
|
|
280
20
|
bootstrapBrokers: ['localhost:9092'],
|
|
281
|
-
clientId: '
|
|
21
|
+
clientId: 'order-producer',
|
|
282
22
|
serializers: stringSerializers,
|
|
283
23
|
});
|
|
284
24
|
|
|
285
|
-
const consumer = KafkaConsumerHelper.newInstance({
|
|
286
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
287
|
-
clientId: 'my-consumer',
|
|
288
|
-
groupId: 'my-group',
|
|
289
|
-
deserializers: stringDeserializers,
|
|
290
|
-
onMessage: async ({ message }) => {
|
|
291
|
-
console.log(message.key, message.value); // both strings
|
|
292
|
-
},
|
|
293
|
-
});
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
### JSON Serialization
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
import {
|
|
300
|
-
jsonSerializer, jsonDeserializer,
|
|
301
|
-
stringSerializer, stringDeserializer,
|
|
302
|
-
serializersFrom, deserializersFrom,
|
|
303
|
-
} from '@platformatic/kafka';
|
|
304
|
-
|
|
305
|
-
const producer = KafkaProducerHelper.newInstance({
|
|
306
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
307
|
-
clientId: 'my-producer',
|
|
308
|
-
serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
|
|
309
|
-
});
|
|
310
|
-
|
|
311
25
|
await producer.getProducer().send({
|
|
312
|
-
messages: [{
|
|
313
|
-
topic: 'orders',
|
|
314
|
-
key: 'order-123',
|
|
315
|
-
value: { id: '123', status: 'created', amount: 99 },
|
|
316
|
-
}],
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
const consumer = KafkaConsumerHelper.newInstance({
|
|
320
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
321
|
-
clientId: 'my-consumer',
|
|
322
|
-
groupId: 'my-group',
|
|
323
|
-
deserializers: { ...deserializersFrom(jsonDeserializer), key: stringDeserializer },
|
|
324
|
-
onMessage: async ({ message }) => {
|
|
325
|
-
console.log(message.value.id, message.value.status); // typed object
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Schema Registry Serialization
|
|
331
|
-
|
|
332
|
-
For schema-validated serialization (Avro, Protobuf, JSON Schema), use the schema registry helper:
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
const registry = KafkaSchemaRegistryHelper.newInstance({
|
|
336
|
-
url: 'http://localhost:8081',
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
const producer = KafkaProducerHelper.newInstance({
|
|
340
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
341
|
-
clientId: 'my-producer',
|
|
342
|
-
registry: registry.getRegistry(),
|
|
26
|
+
messages: [{ topic: 'orders', key: 'order-1', value: JSON.stringify({ status: 'created' }) }],
|
|
343
27
|
});
|
|
344
28
|
|
|
345
|
-
|
|
346
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
347
|
-
clientId: 'my-consumer',
|
|
348
|
-
groupId: 'my-group',
|
|
349
|
-
registry: registry.getRegistry(),
|
|
350
|
-
onMessage: async ({ message }) => {
|
|
351
|
-
// message.value is auto-deserialized using registered schema
|
|
352
|
-
},
|
|
353
|
-
});
|
|
29
|
+
await producer.close();
|
|
354
30
|
```
|
|
355
31
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
## Generic Type Parameters
|
|
32
|
+
`getProducer()` returns the full `@platformatic/kafka` `Producer`. Every helper follows this same pattern: construct through `newInstance()`, reach the native client through `getProducer()` / `getConsumer()` / `getAdmin()`, close through the helper.
|
|
359
33
|
|
|
360
|
-
|
|
34
|
+
## How it works
|
|
361
35
|
|
|
362
|
-
|
|
363
|
-
class KafkaProducerHelper<
|
|
364
|
-
KeyType = string,
|
|
365
|
-
ValueType = string,
|
|
366
|
-
HeaderKeyType = string,
|
|
367
|
-
HeaderValueType = string,
|
|
368
|
-
>
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
| Parameter | Default | Description |
|
|
372
|
-
|-----------|---------|-------------|
|
|
373
|
-
| `KeyType` | `string` | Message key type after serialization/deserialization |
|
|
374
|
-
| `ValueType` | `string` | Message value type after serialization/deserialization |
|
|
375
|
-
| `HeaderKeyType` | `string` | Header key type |
|
|
376
|
-
| `HeaderValueType` | `string` | Header value type |
|
|
36
|
+
- **Four helpers, one job each.**
|
|
377
37
|
|
|
378
|
-
|
|
379
|
-
|
|
38
|
+
| Class | Wraps | Use case |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `KafkaProducerHelper` | `Producer` | Publish messages, run transactions |
|
|
41
|
+
| `KafkaConsumerHelper` | `Consumer` | Consume via consumer groups, monitor lag |
|
|
42
|
+
| `KafkaAdminHelper` | `Admin` | Manage topics, partitions, groups, ACLs, configs |
|
|
43
|
+
| `KafkaSchemaRegistryHelper` | `ConfluentSchemaRegistry` | Schema-validated serialization (Avro/Protobuf/JSON Schema) |
|
|
380
44
|
|
|
381
|
-
|
|
382
|
-
// Default: string types (most common)
|
|
383
|
-
const helper = KafkaProducerHelper.newInstance({ ... });
|
|
45
|
+
- **The three connected helpers share an identical health & close API**, regardless of which client they wrap:
|
|
384
46
|
|
|
385
|
-
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
});
|
|
390
|
-
```
|
|
47
|
+
```typescript
|
|
48
|
+
const producer = KafkaProducerHelper.newInstance({ bootstrapBrokers, clientId });
|
|
49
|
+
const consumer = KafkaConsumerHelper.newInstance({ bootstrapBrokers, clientId, groupId });
|
|
50
|
+
const admin = KafkaAdminHelper.newInstance({ bootstrapBrokers, clientId });
|
|
391
51
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
Centralized default values used by all helpers.
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
import { KafkaDefaults } from '@venizia/ignis-helpers/kafka';
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
| Constant | Value | Scope | Description |
|
|
403
|
-
|----------|-------|-------|-------------|
|
|
404
|
-
| `RETRIES` | `3` | Shared | Connection retry count |
|
|
405
|
-
| `RETRY_DELAY` | `1000` | Shared | Retry delay in ms |
|
|
406
|
-
| `SHUTDOWN_TIMEOUT` | `30000` | Shared | Graceful shutdown timeout in ms |
|
|
407
|
-
| `STRICT` | `true` | Producer | Fail on unknown topics |
|
|
408
|
-
| `AUTOCREATE_TOPICS` | `false` | Producer | Auto-create topics on produce |
|
|
409
|
-
| `AUTOCOMMIT` | `false` | Consumer | Auto-commit offsets |
|
|
410
|
-
| `SESSION_TIMEOUT` | `60000` | Consumer | Session timeout in ms |
|
|
411
|
-
| `HEARTBEAT_INTERVAL` | `10000` | Consumer | Heartbeat interval in ms |
|
|
412
|
-
| `HIGH_WATER_MARK` | `1024` | Consumer | Stream buffer size (messages) |
|
|
413
|
-
| `MIN_BYTES` | `1` | Consumer | Min bytes per fetch |
|
|
414
|
-
| `METADATA_MAX_AGE` | `300000` | Consumer | Metadata cache TTL in ms |
|
|
415
|
-
| `GROUP_PROTOCOL` | `'classic'` | Consumer | Default group protocol |
|
|
416
|
-
| `CONSUME_MODE` | `'committed'` | Consumer | Default consume mode |
|
|
417
|
-
| `CONSUME_FALLBACK_MODE` | `'latest'` | Consumer | Default consume fallback mode |
|
|
418
|
-
| `LAG_MONITOR_INTERVAL` | `30000` | Consumer | Lag monitoring poll interval in ms |
|
|
419
|
-
|
|
420
|
-
### KafkaHealthStatuses
|
|
421
|
-
|
|
422
|
-
Health status values used by all Kafka helpers.
|
|
423
|
-
|
|
424
|
-
```typescript
|
|
425
|
-
import { KafkaHealthStatuses } from '@venizia/ignis-helpers/kafka';
|
|
426
|
-
```
|
|
52
|
+
producer.isHealthy(); // true once at least one broker is connected
|
|
53
|
+
consumer.isReady(); // true once connected AND consumer.isActive()
|
|
54
|
+
admin.getHealthStatus(); // 'connected' | 'disconnected' | 'unknown'
|
|
427
55
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
| `CONNECTED` | `'connected'` | Broker connection established |
|
|
431
|
-
| `DISCONNECTED` | `'disconnected'` | Broker connection lost or closed |
|
|
432
|
-
| `UNKNOWN` | `'unknown'` | Initial state before first broker event |
|
|
56
|
+
await Promise.all([producer.close(), consumer.close(), admin.close()]); // graceful, force fallback
|
|
57
|
+
```
|
|
433
58
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|----------|-------|-------|
|
|
444
|
-
| `BROKER_CONNECT` | `'client:broker:connect'` | All clients |
|
|
445
|
-
| `BROKER_DISCONNECT` | `'client:broker:disconnect'` | All clients |
|
|
446
|
-
| `BROKER_FAILED` | `'client:broker:failed'` | All clients |
|
|
447
|
-
| `CONSUMER_GROUP_JOIN` | `'consumer:group:join'` | Consumer |
|
|
448
|
-
| `CONSUMER_GROUP_LEAVE` | `'consumer:group:leave'` | Consumer |
|
|
449
|
-
| `CONSUMER_GROUP_REBALANCE` | `'consumer:group:rebalance'` | Consumer |
|
|
450
|
-
| `CONSUMER_HEARTBEAT_ERROR` | `'consumer:heartbeat:error'` | Consumer |
|
|
451
|
-
| `CONSUMER_LAG` | `'consumer:lag'` | Consumer |
|
|
452
|
-
| `CONSUMER_LAG_ERROR` | `'consumer:lag:error'` | Consumer |
|
|
453
|
-
| `STREAM_DATA` | `'data'` | Stream |
|
|
454
|
-
| `STREAM_ERROR` | `'error'` | Stream |
|
|
455
|
-
|
|
456
|
-
### KafkaAcks
|
|
457
|
-
|
|
458
|
-
Producer acknowledgment levels.
|
|
459
|
-
|
|
460
|
-
```typescript
|
|
461
|
-
import { KafkaAcks } from '@venizia/ignis-helpers/kafka';
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
| Constant | Value | Description | Trade-off |
|
|
465
|
-
|----------|-------|-------------|-----------|
|
|
466
|
-
| `NONE` | `0` | No acknowledgment -- fire-and-forget | Fastest, no durability guarantee |
|
|
467
|
-
| `LEADER` | `1` | Leader broker acknowledges | Fast, leader-durable |
|
|
468
|
-
| `ALL` | `-1` | All in-sync replicas acknowledge | Slowest, fully durable |
|
|
469
|
-
|
|
470
|
-
### KafkaGroupProtocol
|
|
471
|
-
|
|
472
|
-
Consumer group protocol versions.
|
|
473
|
-
|
|
474
|
-
```typescript
|
|
475
|
-
import { KafkaGroupProtocol } from '@venizia/ignis-helpers/kafka';
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
| Constant | Value | Description |
|
|
479
|
-
|----------|-------|-------------|
|
|
480
|
-
| `CLASSIC` | `'classic'` | Classic consumer group protocol (default, all Kafka versions) |
|
|
481
|
-
| `CONSUMER` | `'consumer'` | New consumer group protocol -- KIP-848 (Kafka 3.7+) |
|
|
482
|
-
|
|
483
|
-
### Derived Types
|
|
484
|
-
|
|
485
|
-
```typescript
|
|
486
|
-
import type { TKafkaAcks, TKafkaGroupProtocol, TKafkaHealthStatus } from '@venizia/ignis-helpers/kafka';
|
|
487
|
-
|
|
488
|
-
// TKafkaAcks = 0 | 1 | -1
|
|
489
|
-
// TKafkaGroupProtocol = 'classic' | 'consumer'
|
|
490
|
-
// TKafkaHealthStatus = 'connected' | 'disconnected' | 'unknown'
|
|
491
|
-
```
|
|
59
|
+
```
|
|
60
|
+
BaseHelper (scoped logging, identifier)
|
|
61
|
+
+-- BaseKafkaHelper<TClient> (health tracking, broker events, graceful shutdown)
|
|
62
|
+
| +-- KafkaProducerHelper<K,V,HK,HV>
|
|
63
|
+
| +-- KafkaConsumerHelper<K,V,HK,HV>
|
|
64
|
+
| +-- KafkaAdminHelper
|
|
65
|
+
|
|
|
66
|
+
+-- KafkaSchemaRegistryHelper<K,V,HK,HV> (no broker connection)
|
|
67
|
+
```
|
|
492
68
|
|
|
493
|
-
|
|
69
|
+
- **`BaseKafkaHelper` is the shared base** for the three connected helpers (everything but the schema registry). It tracks per-broker connection state (`host:port` keys), so one idle disconnect never flips `isHealthy()` to `false` - only when every broker is gone. `isReady()`, `getHealthStatus()`, and `getConnectedBrokerCount()` read the same state, and `close({ isForce })` gives every connected helper the same two-phase graceful-then-force shutdown.
|
|
70
|
+
- **Health status follows broker events automatically.** `client:broker:connect` marks a broker connected; `client:broker:disconnect` and `client:broker:failed` remove it and only flip the status to `'disconnected'` once every broker is gone; `close()` clears everything. You never set `healthStatus` yourself.
|
|
71
|
+
- **`KafkaSchemaRegistryHelper` extends `BaseHelper` directly.** It opens no broker connection, so it has no health tracking - it's a configuration wrapper you hand to a producer or consumer via `registry`.
|
|
72
|
+
- **Everything lives at the `/kafka` sub-path, never the root barrel.** `@platformatic/kafka` is an optional peer dependency (`^2.1.0` - `bun add @platformatic/kafka`); keeping it off the root barrel lets apps that never touch Kafka tree-shake it away entirely.
|
|
73
|
+
- **Generics default to `string`.** All four classes accept `<KeyType, ValueType, HeaderKeyType, HeaderValueType>` generics. Without serializers/deserializers, messages travel as raw `Buffer`.
|
|
74
|
+
- **`newInstance()` is the documented entry point.** Every class also exposes a public constructor, but `newInstance()` is what every example on these pages uses, and it carries the same generic inference: `KafkaProducerHelper.newInstance<string, MyEvent>({ ... })`.
|
|
75
|
+
- **Compiling to a single binary needs one extra step.** `bun build --compile` crashes at startup with `ENOENT: native.wasm` unless the build registers `platformaticWasmPlugin()` - see [Compiling to a Single Binary](./compile-binary).
|
|
494
76
|
|
|
495
|
-
`@
|
|
77
|
+
**Exported constants** (`@venizia/ignis-helpers/kafka`):
|
|
496
78
|
|
|
497
|
-
|
|
|
498
|
-
|
|
499
|
-
|
|
|
500
|
-
|
|
|
501
|
-
|
|
|
502
|
-
|
|
|
503
|
-
|
|
|
79
|
+
| Constant | Exports | Purpose |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `KafkaDefaults` | Timeouts, retry counts, buffer sizes | Every default value the helpers fall back to |
|
|
82
|
+
| `KafkaAcks` | `NONE` (`0`) / `LEADER` (`1`) / `ALL` (`-1`) | Producer acknowledgment levels |
|
|
83
|
+
| `KafkaGroupProtocol` | `CLASSIC` / `CONSUMER` | Consumer group protocol version |
|
|
84
|
+
| `KafkaHealthStatuses` | `CONNECTED` / `DISCONNECTED` / `UNKNOWN` | `getHealthStatus()` return values |
|
|
85
|
+
| `KafkaClientEvents` | Raw platformatic event names | Direct listening on `getProducer()` / `getConsumer()` / `getAdmin()` |
|
|
504
86
|
|
|
505
|
-
|
|
506
|
-
const helper = KafkaProducerHelper.newInstance({
|
|
507
|
-
bootstrapBrokers: ['localhost:9092'],
|
|
508
|
-
clientId: 'my-producer',
|
|
509
|
-
serializers: stringSerializers,
|
|
510
|
-
compression: 'zstd',
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
// Override per-send
|
|
514
|
-
await helper.getProducer().send({
|
|
515
|
-
messages: [{ topic: 'logs', key: 'l1', value: largePayload }],
|
|
516
|
-
compression: 'lz4',
|
|
517
|
-
});
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
## Quick Usage Comparison
|
|
521
|
-
|
|
522
|
-
### Construction
|
|
523
|
-
|
|
524
|
-
```typescript
|
|
525
|
-
// Admin
|
|
526
|
-
const admin = KafkaAdminHelper.newInstance({
|
|
527
|
-
bootstrapBrokers: ['127.0.0.1:29092'],
|
|
528
|
-
clientId: 'my-admin',
|
|
529
|
-
onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
|
|
530
|
-
onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
// Producer
|
|
534
|
-
const producer = KafkaProducerHelper.newInstance({
|
|
535
|
-
bootstrapBrokers: ['127.0.0.1:29092'],
|
|
536
|
-
clientId: 'my-producer',
|
|
537
|
-
acks: -1,
|
|
538
|
-
idempotent: true,
|
|
539
|
-
transactionalId: 'my-tx',
|
|
540
|
-
onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
|
|
541
|
-
onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
// Consumer
|
|
545
|
-
const consumer = KafkaConsumerHelper.newInstance({
|
|
546
|
-
bootstrapBrokers: ['127.0.0.1:29092'],
|
|
547
|
-
clientId: 'my-consumer',
|
|
548
|
-
groupId: 'my-group',
|
|
549
|
-
onBrokerConnect: ({ broker }) => console.log(`Connected to ${broker.host}`),
|
|
550
|
-
onBrokerDisconnect: ({ broker }) => console.log(`Disconnected from ${broker.host}`),
|
|
551
|
-
onMessage: async ({ message }) => {
|
|
552
|
-
console.log('Received:', message.value);
|
|
553
|
-
await message.commit();
|
|
554
|
-
},
|
|
555
|
-
onMessageDone: ({ message }) => console.log('Done:', message.key),
|
|
556
|
-
onMessageError: ({ error, message }) => console.error('Error:', error),
|
|
557
|
-
onGroupJoin: ({ groupId, memberId }) => console.log(`Joined ${groupId}`),
|
|
558
|
-
onGroupLeave: ({ groupId }) => console.log(`Left ${groupId}`),
|
|
559
|
-
onGroupRebalance: ({ groupId }) => console.log(`Rebalance ${groupId}`),
|
|
560
|
-
onHeartbeatError: ({ error }) => console.error('Heartbeat:', error),
|
|
561
|
-
onLag: ({ lag }) => console.log('Lag:', lag),
|
|
562
|
-
onLagError: ({ error }) => console.error('Lag error:', error),
|
|
563
|
-
});
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
### Core Operations
|
|
567
|
-
|
|
568
|
-
| Admin | Producer | Consumer |
|
|
569
|
-
|-------|----------|----------|
|
|
570
|
-
| `admin.getAdmin()` | `producer.getProducer()` | `consumer.getConsumer()` |
|
|
571
|
-
| -- | `producer.getProducer().send(...)` | `await consumer.start({ topics: ['t1'] })` |
|
|
572
|
-
| -- | `await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => { ... })` | `consumer.startLagMonitoring({ topics: ['t1'], interval: 10_000 })` |
|
|
573
|
-
| -- | -- | `consumer.stopLagMonitoring()` |
|
|
574
|
-
| -- | -- | `consumer.getStream()` |
|
|
575
|
-
|
|
576
|
-
### Health Checks
|
|
577
|
-
|
|
578
|
-
```typescript
|
|
579
|
-
// All three -- identical API
|
|
580
|
-
helper.isHealthy(); // true when at least one broker connected
|
|
581
|
-
helper.isReady(); // Admin/Producer: same as isHealthy()
|
|
582
|
-
// Consumer: isHealthy() + consumer.isActive()
|
|
583
|
-
helper.getHealthStatus(); // 'connected' | 'disconnected' | 'unknown'
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
### Shutdown
|
|
587
|
-
|
|
588
|
-
```typescript
|
|
589
|
-
// All three -- identical API
|
|
590
|
-
await helper.close(); // graceful (timeout -> force fallback)
|
|
591
|
-
await helper.close({ isForce: true }); // immediate force close
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### With Schema Registry
|
|
595
|
-
|
|
596
|
-
```typescript
|
|
597
|
-
const registry = KafkaSchemaRegistryHelper.newInstance({ url: 'http://localhost:8081' });
|
|
598
|
-
|
|
599
|
-
const producer = KafkaProducerHelper.newInstance({
|
|
600
|
-
...,
|
|
601
|
-
registry: registry.getRegistry(),
|
|
602
|
-
// or use registry.getSerializers() for manual serializer config
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
const consumer = KafkaConsumerHelper.newInstance({
|
|
606
|
-
...,
|
|
607
|
-
registry: registry.getRegistry(),
|
|
608
|
-
// or use registry.getDeserializers() for manual deserializer config
|
|
609
|
-
});
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### Transaction (Producer Only)
|
|
613
|
-
|
|
614
|
-
```typescript
|
|
615
|
-
const result = await producer.runInTransaction(async ({ send, addConsumer, addOffset }) => {
|
|
616
|
-
// Send messages within transaction
|
|
617
|
-
const result = await send({
|
|
618
|
-
messages: [{ topic: 'orders', key: 'o1', value: '{"status":"created"}' }],
|
|
619
|
-
});
|
|
87
|
+
## Pages
|
|
620
88
|
|
|
621
|
-
|
|
622
|
-
await addConsumer(consumer.getConsumer());
|
|
623
|
-
await addOffset(message);
|
|
89
|
+
Each class, and the one build-time gotcha, gets its own page:
|
|
624
90
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
91
|
+
| Page | Covers |
|
|
92
|
+
|---|---|
|
|
93
|
+
| [Producer](./producer) | `KafkaProducerHelper` - connection & SASL setup, serialization, compression, transactions, full `Producer` API |
|
|
94
|
+
| [Consumer](./consumer) | `KafkaConsumerHelper` - message callbacks, automatic reconnect, lag monitoring, full `Consumer` API |
|
|
95
|
+
| [Admin](./admin) | `KafkaAdminHelper` - topic, group, offset, ACL, and quota management |
|
|
96
|
+
| [Schema Registry](./schema-registry) | `KafkaSchemaRegistryHelper` for Avro/Protobuf/JSON Schema validated messages |
|
|
97
|
+
| [Compiling to a Single Binary](./compile-binary) | The `platformaticWasmPlugin()` fix for `bun build --compile` |
|
|
98
|
+
| [Examples & Troubleshooting](./examples) | End-to-end examples, IoC wiring, common errors |
|
|
628
99
|
|
|
629
|
-
|
|
100
|
+
Start with [Producer](./producer) or [Consumer](./consumer) if you're wiring up your first topic; start with [Compiling to a Single Binary](./compile-binary) if an existing app just started throwing `ENOENT: native.wasm` after a `bun build --compile`.
|
|
630
101
|
|
|
631
|
-
|
|
632
|
-
- **[Consumer](./consumer)** -- Consumer helper, message callbacks, lag monitoring, and full Consumer API reference
|
|
633
|
-
- **[Admin](./admin)** -- Admin helper and full Admin API reference
|
|
634
|
-
- **[Schema Registry](./schema-registry)** -- Schema registry helper for Avro/Protobuf/JSON Schema validation
|
|
635
|
-
- **[Examples & Troubleshooting](./examples)** -- Complete examples, IoC integration, and troubleshooting guide
|
|
102
|
+
## See also
|
|
636
103
|
|
|
637
|
-
|
|
104
|
+
- [Queue Helpers](../queue/) - BullMQ, MQTT, and the in-memory queue: the other three queueing backends
|
|
105
|
+
- [Redis Helper](../redis/) - connection management used elsewhere in the helpers package
|
|
106
|
+
- [Kafka Helpers Enhancement](/changelogs/2026-03-12-kafka-helpers-enhancement) / [Kafka Helpers Refactor](/changelogs/2026-03-10-kafka-helpers-refactor) - changelog history for this module
|
|
107
|
+
- [@platformatic/kafka](https://github.com/platformatic/kafka) - the underlying Kafka client library
|
|
108
|
+
- [Apache Kafka Documentation](https://kafka.apache.org/documentation/) - official Kafka docs
|
|
109
|
+
- [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848) - the new consumer group protocol
|
|
638
110
|
|
|
639
|
-
|
|
640
|
-
- [Queue Helper](../queue/) -- BullMQ, MQTT, and in-memory queues
|
|
641
|
-
- [Redis Helper](../redis/) -- Redis connection management
|
|
111
|
+
**Files:**
|
|
642
112
|
|
|
643
|
-
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
113
|
+
- [`packages/helpers/src/modules/queue/kafka/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/base.ts) - `BaseKafkaHelper`, health tracking, broker events
|
|
114
|
+
- [`packages/helpers/src/modules/queue/kafka/index.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/index.ts) - the `/kafka` sub-path barrel
|
|
115
|
+
- [`packages/helpers/src/modules/queue/kafka/common/constants.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/common/constants.ts) - `KafkaDefaults`, `KafkaAcks`, `KafkaGroupProtocol`, `KafkaHealthStatuses`, `KafkaClientEvents`
|
|
116
|
+
- [`packages/helpers/src/modules/queue/kafka/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/common/types.ts) - every `IKafka*` / `TKafka*` type
|