@venizia/ignis-docs 0.0.7-1 → 0.0.7-2

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.
@@ -0,0 +1,234 @@
1
+ # Examples & Troubleshooting
2
+
3
+ Complete examples and common issue resolution for the Kafka helpers.
4
+
5
+ ## Producer: Interval-Based Message Sending
6
+
7
+ ```typescript
8
+ import { Producer, serializersFrom, jsonSerializer, stringSerializer } from '@platformatic/kafka';
9
+
10
+ const producer = new Producer({
11
+ clientId: 'interval-producer',
12
+ bootstrapBrokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],
13
+ serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
14
+ sasl: { mechanism: 'SCRAM-SHA-512', username: 'user', password: 'pass' },
15
+ connectTimeout: 30_000,
16
+ requestTimeout: 30_000,
17
+ });
18
+
19
+ let count = 0;
20
+ const interval = setInterval(async () => {
21
+ const key = `key-${count % 3}`;
22
+ const value = { index: count, timestamp: new Date().toISOString() };
23
+
24
+ await producer.send({ messages: [{ topic: 'events', key, value }] });
25
+ console.log(JSON.stringify({ topic: 'events', key, value }));
26
+ count++;
27
+ }, 100);
28
+
29
+ process.on('SIGINT', async () => {
30
+ clearInterval(interval);
31
+ console.log(`Shutting down... (sent ${count} messages)`);
32
+ await producer.close();
33
+ process.exit(0);
34
+ });
35
+ ```
36
+
37
+ ## Consumer: Event-Based with Manual Commit
38
+
39
+ ```typescript
40
+ import { Consumer, deserializersFrom, jsonDeserializer, stringDeserializer } from '@platformatic/kafka';
41
+
42
+ const consumer = new Consumer({
43
+ clientId: 'event-consumer',
44
+ bootstrapBrokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],
45
+ groupId: 'processing-group',
46
+ deserializers: { ...deserializersFrom(jsonDeserializer), key: stringDeserializer },
47
+ sasl: { mechanism: 'SCRAM-SHA-512', username: 'user', password: 'pass' },
48
+ connectTimeout: 30_000,
49
+ requestTimeout: 30_000,
50
+ autocommit: false,
51
+ });
52
+
53
+ const stream = await consumer.consume({
54
+ topics: ['events'],
55
+ mode: 'committed',
56
+ fallbackMode: 'latest',
57
+ });
58
+
59
+ stream.on('data', (message) => {
60
+ console.log(JSON.stringify({
61
+ topic: message.topic,
62
+ partition: message.partition,
63
+ offset: message.offset,
64
+ key: message.key,
65
+ value: message.value,
66
+ headers: Object.fromEntries(message.headers ?? new Map()),
67
+ timestamp: message.timestamp,
68
+ }, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)));
69
+
70
+ message.commit();
71
+ });
72
+
73
+ stream.on('error', (err) => console.error('Stream error:', err));
74
+
75
+ process.on('SIGINT', async () => {
76
+ await stream.close();
77
+ await consumer.close();
78
+ process.exit(0);
79
+ });
80
+ ```
81
+
82
+ ## Admin: Topic Setup Script
83
+
84
+ ```typescript
85
+ import { KafkaAdminHelper } from '@venizia/ignis-helpers/kafka';
86
+
87
+ async function setupTopics() {
88
+ const helper = KafkaAdminHelper.newInstance({
89
+ bootstrapBrokers: ['localhost:9092'],
90
+ clientId: 'topic-setup',
91
+ });
92
+
93
+ const admin = helper.getAdmin();
94
+
95
+ // Create topics
96
+ await admin.createTopics({
97
+ topics: ['orders', 'inventory', 'notifications'],
98
+ partitions: 6,
99
+ replicas: 3,
100
+ configs: [
101
+ { name: 'retention.ms', value: '604800000' },
102
+ { name: 'compression.type', value: 'zstd' },
103
+ ],
104
+ });
105
+
106
+ // Verify
107
+ const topics = await admin.listTopics({ includeInternals: false });
108
+ console.log('Topics:', topics);
109
+
110
+ await helper.close();
111
+ }
112
+
113
+ setupTopics();
114
+ ```
115
+
116
+ ## Using Helpers with Ignis IoC
117
+
118
+ ```typescript
119
+ import { KafkaProducerHelper, KafkaConsumerHelper } from '@venizia/ignis-helpers/kafka';
120
+ import { stringSerializers, stringDeserializers } from '@platformatic/kafka';
121
+ import { inject, injectable } from '@venizia/ignis-inversion';
122
+
123
+ @injectable()
124
+ export class OrderEventService {
125
+ private producer: KafkaProducerHelper;
126
+ private consumer: KafkaConsumerHelper;
127
+
128
+ constructor(
129
+ @inject({ key: 'kafka.producer' }) producer: KafkaProducerHelper,
130
+ @inject({ key: 'kafka.consumer' }) consumer: KafkaConsumerHelper,
131
+ ) {
132
+ this.producer = producer;
133
+ this.consumer = consumer;
134
+ }
135
+
136
+ async publishOrderCreated(orderId: string, data: Record<string, unknown>) {
137
+ const producer = this.producer.getProducer();
138
+ await producer.send({
139
+ messages: [{ topic: 'order-events', key: orderId, value: JSON.stringify(data) }],
140
+ });
141
+ }
142
+
143
+ async startConsuming() {
144
+ const consumer = this.consumer.getConsumer();
145
+ const stream = await consumer.consume({
146
+ topics: ['order-events'],
147
+ mode: 'committed',
148
+ fallbackMode: 'latest',
149
+ });
150
+
151
+ for await (const message of stream) {
152
+ await this.handleOrderEvent(message.key!, JSON.parse(message.value!));
153
+ await message.commit();
154
+ }
155
+ }
156
+
157
+ private async handleOrderEvent(orderId: string, data: Record<string, unknown>) {
158
+ // Process order event
159
+ }
160
+ }
161
+
162
+ // Register in application
163
+ app.bind('kafka.producer').to(
164
+ KafkaProducerHelper.newInstance({
165
+ bootstrapBrokers: ['localhost:9092'],
166
+ clientId: 'order-service-producer',
167
+ serializers: stringSerializers,
168
+ }),
169
+ );
170
+
171
+ app.bind('kafka.consumer').to(
172
+ KafkaConsumerHelper.newInstance({
173
+ bootstrapBrokers: ['localhost:9092'],
174
+ clientId: 'order-service-consumer',
175
+ groupId: 'order-service',
176
+ deserializers: stringDeserializers,
177
+ }),
178
+ );
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Troubleshooting
184
+
185
+ ### Common Issues
186
+
187
+ | Error | Cause | Fix |
188
+ |-------|-------|-----|
189
+ | `ECONNREFUSED localhost:9092` | Broker `advertised.listeners` set to `localhost` but connecting remotely | Set `KAFKA_ADVERTISED_LISTENERS` with the correct external host IP |
190
+ | `Request timed out` | SASL handshake or broker unreachable | Add `connectTimeout: 30_000, requestTimeout: 30_000` |
191
+ | `Connection closed` | Connecting without SASL to a SASL-required listener | Check `KAFKA_LISTENER_SECURITY_PROTOCOL_MAP` — use `SASL_PLAINTEXT` |
192
+ | `Cannot find a suitable SASL mechanism` | Wrong mechanism (e.g., `PLAIN` when broker only supports `SCRAM-SHA-512`) | Check error message for supported mechanisms, match `mechanism` |
193
+ | `Failed to deserialize a message` | Mismatch between serializer used for producing and deserializer used for consuming | Ensure matching serde. For old data, use a new consumer group or recreate topic |
194
+ | `JSON.stringify cannot serialize BigInt` | `message.offset` and `message.timestamp` are `bigint` | Use custom replacer: `(_k, v) => typeof v === 'bigint' ? v.toString() : v` |
195
+ | Consumer idle (no messages) | More consumers than partitions | Ensure `numPartitions >= numConsumers` |
196
+
197
+ ### Docker Kafka Configuration
198
+
199
+ When running Kafka in Docker and connecting from outside the container:
200
+
201
+ ```yaml
202
+ environment:
203
+ DOCKER_HOST_IP: '192.168.1.100' # Your host machine's IP
204
+ KAFKA_ADVERTISED_LISTENERS: >
205
+ INTERNAL://kafka-1:29092,
206
+ EXTERNAL://${DOCKER_HOST_IP}:19092
207
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: >
208
+ INTERNAL:PLAINTEXT,
209
+ EXTERNAL:SASL_PLAINTEXT,
210
+ CONTROLLER:PLAINTEXT
211
+ ```
212
+
213
+ - `INTERNAL` — used for inter-broker communication
214
+ - `EXTERNAL` — used for client connections from outside Docker
215
+ - `CONTROLLER` — used for KRaft controller communication
216
+
217
+ ---
218
+
219
+ ## See Also
220
+
221
+ - **Kafka Pages:**
222
+ - [Overview & Fundamentals](./) — Connection, serialization, constants, compression
223
+ - [Producer](./producer) — Producer helper & API reference
224
+ - [Consumer](./consumer) — Consumer helper & API reference
225
+ - [Admin](./admin) — Admin helper & API reference
226
+
227
+ - **Other Helpers:**
228
+ - [Queue Helper](../queue/) — BullMQ, MQTT, and in-memory queues
229
+ - [Redis Helper](../redis/) — Redis connection management
230
+
231
+ - **External Resources:**
232
+ - [@platformatic/kafka](https://github.com/platformatic/kafka) — Underlying Kafka client library
233
+ - [Apache Kafka Documentation](https://kafka.apache.org/documentation/) — Official Kafka docs
234
+ - [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848) — New consumer group protocol