@venizia/ignis-docs 0.2.0 → 0.2.1-1

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.
Files changed (174) hide show
  1. package/README.md +14 -14
  2. package/content/best-practices/api-usage-examples.md +39 -19
  3. package/content/best-practices/architectural-patterns.md +24 -13
  4. package/content/best-practices/architecture-decisions.md +29 -16
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
  6. package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
  7. package/content/best-practices/code-style-standards/control-flow.md +33 -1
  8. package/content/best-practices/code-style-standards/documentation.md +28 -8
  9. package/content/best-practices/code-style-standards/function-patterns.md +15 -4
  10. package/content/best-practices/code-style-standards/index.md +7 -2
  11. package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
  12. package/content/best-practices/code-style-standards/route-definitions.md +9 -5
  13. package/content/best-practices/code-style-standards/tooling.md +14 -1
  14. package/content/best-practices/code-style-standards/type-safety.md +39 -6
  15. package/content/best-practices/common-pitfalls.md +59 -35
  16. package/content/best-practices/contribution-workflow.md +8 -4
  17. package/content/best-practices/data-modeling.md +78 -62
  18. package/content/best-practices/deployment-strategies.md +56 -19
  19. package/content/best-practices/error-handling.md +247 -153
  20. package/content/best-practices/index.md +6 -0
  21. package/content/best-practices/performance-optimization.md +26 -13
  22. package/content/best-practices/security-guidelines.md +35 -9
  23. package/content/best-practices/testing-strategies.md +7 -2
  24. package/content/best-practices/troubleshooting-tips.md +27 -17
  25. package/content/extensions/components/api-reference.md +109 -323
  26. package/content/extensions/components/authentication/api.md +489 -602
  27. package/content/extensions/components/authentication/errors.md +135 -498
  28. package/content/extensions/components/authentication/index.md +89 -801
  29. package/content/extensions/components/authentication/usage.md +231 -955
  30. package/content/extensions/components/authorization/api.md +991 -644
  31. package/content/extensions/components/authorization/errors.md +204 -208
  32. package/content/extensions/components/authorization/getting-started.md +227 -0
  33. package/content/extensions/components/authorization/index.md +88 -795
  34. package/content/extensions/components/authorization/usage.md +219 -528
  35. package/content/extensions/components/health-check.md +77 -243
  36. package/content/extensions/components/index.md +24 -90
  37. package/content/extensions/components/mail/api.md +553 -285
  38. package/content/extensions/components/mail/errors.md +76 -62
  39. package/content/extensions/components/mail/index.md +111 -463
  40. package/content/extensions/components/mail/usage.md +139 -173
  41. package/content/extensions/components/request-tracker.md +70 -173
  42. package/content/extensions/components/socket-io/api.md +462 -785
  43. package/content/extensions/components/socket-io/errors.md +49 -51
  44. package/content/extensions/components/socket-io/index.md +69 -372
  45. package/content/extensions/components/socket-io/usage.md +212 -105
  46. package/content/extensions/components/static-asset/api.md +461 -141
  47. package/content/extensions/components/static-asset/errors.md +121 -53
  48. package/content/extensions/components/static-asset/index.md +84 -606
  49. package/content/extensions/components/static-asset/usage.md +184 -299
  50. package/content/extensions/components/template/index.md +3 -3
  51. package/content/extensions/components/websocket/api.md +311 -404
  52. package/content/extensions/components/websocket/errors.md +47 -56
  53. package/content/extensions/components/websocket/index.md +75 -407
  54. package/content/extensions/components/websocket/usage.md +120 -338
  55. package/content/extensions/helpers/cron/index.md +52 -160
  56. package/content/extensions/helpers/crypto/index.md +67 -480
  57. package/content/extensions/helpers/crypto/reference.md +528 -0
  58. package/content/extensions/helpers/env/index.md +64 -178
  59. package/content/extensions/helpers/error/index.md +286 -196
  60. package/content/extensions/helpers/index.md +61 -47
  61. package/content/extensions/helpers/inversion/index.md +76 -550
  62. package/content/extensions/helpers/inversion/reference.md +530 -0
  63. package/content/extensions/helpers/kafka/admin.md +23 -3
  64. package/content/extensions/helpers/kafka/compile-binary.md +83 -52
  65. package/content/extensions/helpers/kafka/consumer.md +65 -28
  66. package/content/extensions/helpers/kafka/examples.md +46 -253
  67. package/content/extensions/helpers/kafka/index.md +55 -617
  68. package/content/extensions/helpers/kafka/producer.md +156 -22
  69. package/content/extensions/helpers/kafka/schema-registry.md +59 -79
  70. package/content/extensions/helpers/logger/hf-logger.md +220 -0
  71. package/content/extensions/helpers/logger/index.md +78 -552
  72. package/content/extensions/helpers/logger/pino.md +105 -0
  73. package/content/extensions/helpers/logger/reference.md +937 -0
  74. package/content/extensions/helpers/network/api.md +276 -195
  75. package/content/extensions/helpers/network/index.md +87 -524
  76. package/content/extensions/helpers/queue/index.md +80 -897
  77. package/content/extensions/helpers/queue/reference.md +494 -0
  78. package/content/extensions/helpers/redis/index.md +86 -640
  79. package/content/extensions/helpers/redis/reference.md +784 -0
  80. package/content/extensions/helpers/secrets/index.md +136 -0
  81. package/content/extensions/helpers/socket-io/api.md +325 -204
  82. package/content/extensions/helpers/socket-io/index.md +79 -429
  83. package/content/extensions/helpers/storage/api.md +584 -464
  84. package/content/extensions/helpers/storage/index.md +80 -573
  85. package/content/extensions/helpers/types/index.md +75 -495
  86. package/content/extensions/helpers/types/reference.md +689 -0
  87. package/content/extensions/helpers/uid/index.md +176 -189
  88. package/content/extensions/helpers/websocket/api.md +366 -214
  89. package/content/extensions/helpers/websocket/index.md +68 -503
  90. package/content/extensions/helpers/worker-thread/index.md +62 -396
  91. package/content/extensions/helpers/worker-thread/reference.md +428 -0
  92. package/content/extensions/index.md +38 -39
  93. package/content/extensions/src-details/mcp-server.md +96 -548
  94. package/content/guides/core-concepts/persistent/datasources.md +2 -2
  95. package/content/guides/core-concepts/persistent/index.md +5 -1
  96. package/content/guides/core-concepts/persistent/models.md +1 -1
  97. package/content/guides/core-concepts/persistent/pglite.md +218 -0
  98. package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
  99. package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
  100. package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
  101. package/content/guides/core-concepts/persistent/sqlite.md +296 -0
  102. package/content/guides/core-concepts/persistent/transactions.md +12 -11
  103. package/content/guides/core-concepts/secrets-vault.md +177 -0
  104. package/content/guides/core-concepts/services.md +1 -1
  105. package/content/guides/get-started/5-minute-quickstart.md +59 -206
  106. package/content/guides/get-started/philosophy.md +135 -670
  107. package/content/guides/get-started/setup.md +53 -74
  108. package/content/guides/migrations/redis-helpers-migration.md +5 -4
  109. package/content/guides/migrations/scoped-rbac-migration.md +5 -5
  110. package/content/guides/migrations/unified-connectors-migration.md +8 -7
  111. package/content/guides/tutorials/ecommerce-api.md +3 -8
  112. package/content/guides/tutorials/realtime-chat.md +1 -1
  113. package/content/references/base/application.md +64 -22
  114. package/content/references/base/components.md +3 -3
  115. package/content/references/base/connectors.md +79 -136
  116. package/content/references/base/controllers.md +12 -12
  117. package/content/references/base/datasources-reference.md +600 -0
  118. package/content/references/base/datasources.md +84 -444
  119. package/content/references/base/dependency-injection.md +25 -46
  120. package/content/references/base/filter-system/application-usage.md +95 -123
  121. package/content/references/base/filter-system/array-operators.md +33 -43
  122. package/content/references/base/filter-system/comparison-operators.md +55 -63
  123. package/content/references/base/filter-system/default-filter.md +144 -350
  124. package/content/references/base/filter-system/fields-order-pagination.md +116 -148
  125. package/content/references/base/filter-system/index.md +114 -253
  126. package/content/references/base/filter-system/json-filtering.md +52 -181
  127. package/content/references/base/filter-system/list-operators.md +28 -44
  128. package/content/references/base/filter-system/logical-operators.md +69 -114
  129. package/content/references/base/filter-system/null-operators.md +41 -98
  130. package/content/references/base/filter-system/pattern-matching.md +48 -51
  131. package/content/references/base/filter-system/quick-reference.md +93 -196
  132. package/content/references/base/filter-system/range-operators.md +22 -38
  133. package/content/references/base/filter-system/tips.md +70 -133
  134. package/content/references/base/filter-system/use-cases.md +173 -232
  135. package/content/references/base/grpc-controllers.md +53 -17
  136. package/content/references/base/index.md +5 -3
  137. package/content/references/base/middlewares.md +43 -28
  138. package/content/references/base/models-reference.md +886 -0
  139. package/content/references/base/models.md +81 -1452
  140. package/content/references/base/providers.md +8 -8
  141. package/content/references/base/repositories/advanced.md +281 -419
  142. package/content/references/base/repositories/index.md +84 -644
  143. package/content/references/base/repositories/mixins.md +25 -21
  144. package/content/references/base/repositories/relations.md +194 -375
  145. package/content/references/base/repositories/soft-deletable.md +67 -55
  146. package/content/references/base/secrets.md +267 -0
  147. package/content/references/base/services.md +8 -6
  148. package/content/references/configuration/environment-variables.md +73 -21
  149. package/content/references/configuration/index.md +51 -31
  150. package/content/references/index.md +1 -1
  151. package/content/references/quick-reference.md +3 -16
  152. package/content/references/utilities/crypto.md +35 -76
  153. package/content/references/utilities/date.md +33 -73
  154. package/content/references/utilities/duration.md +85 -0
  155. package/content/references/utilities/index.md +6 -2
  156. package/content/references/utilities/jsx-reference.md +298 -0
  157. package/content/references/utilities/jsx.md +82 -525
  158. package/content/references/utilities/module.md +81 -61
  159. package/content/references/utilities/parse.md +34 -64
  160. package/content/references/utilities/performance.md +33 -58
  161. package/content/references/utilities/promise.md +28 -62
  162. package/content/references/utilities/request.md +58 -218
  163. package/content/references/utilities/retry.md +139 -0
  164. package/content/references/utilities/schema.md +43 -137
  165. package/content/references/utilities/statuses-reference.md +361 -0
  166. package/content/references/utilities/statuses.md +63 -667
  167. package/dist/mcp-server/index.js +0 -0
  168. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  169. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
  170. package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
  171. package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
  172. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
  173. package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
  174. package/package.json +24 -23
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: Kafka Producer
3
+ description: KafkaProducerHelper - connection, SASL, serialization, compression, and transactions
4
+ difficulty: intermediate
5
+ ---
6
+
1
7
  # Producer
2
8
 
3
9
  The `KafkaProducerHelper` wraps `@platformatic/kafka`'s `Producer` with health tracking, graceful shutdown, broker event callbacks, and a transaction helper.
@@ -34,19 +40,61 @@ interface IKafkaProducerOptions<KeyType, ValueType, HeaderKeyType, HeaderValueTy
34
40
  | Option | Type | Default | Description |
35
41
  |--------|------|---------|-------------|
36
42
  | `identifier` | `string` | `'kafka-producer'` | Scoped logging identifier |
37
- | `serializers` | `Partial<Serializers<K,V,HK,HV>>` | -- | Key/value/header serializers |
38
- | `compression` | `CompressionAlgorithmValue` | -- | `'none'`, `'gzip'`, `'snappy'`, `'lz4'`, `'zstd'` |
39
- | `acks` | `TKafkaAcks` | -- | Acknowledgment level: `0`, `1`, or `-1` |
40
- | `idempotent` | `boolean` | -- | Enable idempotent producer (exactly-once within partition) |
41
- | `transactionalId` | `string` | -- | Transactional ID for exactly-once across partitions |
42
- | `strict` | `boolean` | `true` | Strict mode -- fail on unknown topics |
43
+ | `serializers` | `Partial<Serializers<K,V,HK,HV>>` | - | Key/value/header serializers |
44
+ | `compression` | `CompressionAlgorithmValue` | - | `'none'`, `'gzip'`, `'snappy'`, `'lz4'`, `'zstd'` |
45
+ | `acks` | `TKafkaAcks` | - | Acknowledgment level: `0` (none), `1` (leader), `-1` (all) |
46
+ | `idempotent` | `boolean` | - | Enable idempotent producer (exactly-once within partition) |
47
+ | `transactionalId` | `string` | - | Transactional ID for exactly-once across partitions |
48
+ | `strict` | `boolean` | `true` | Strict mode - fail on unknown topics |
43
49
  | `autocreateTopics` | `boolean` | `false` | Auto-create topics on first produce |
44
50
  | `shutdownTimeout` | `number` | `30000` | Graceful shutdown timeout in ms |
45
- | `registry` | `SchemaRegistry` | -- | Schema registry for auto ser/deser |
46
- | `onBrokerConnect` | `TKafkaBrokerEventCallback` | -- | Called when broker connects |
47
- | `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | -- | Called when broker disconnects |
51
+ | `registry` | `SchemaRegistry` | - | Schema registry for auto ser/deser |
52
+ | `onBrokerConnect` | `TKafkaBrokerEventCallback` | - | Called when broker connects |
53
+ | `onBrokerDisconnect` | `TKafkaBrokerEventCallback` | - | Called when broker disconnects |
54
+
55
+ Plus the shared [Connection & Authentication](#connection--authentication) options below, all inherited from `IKafkaConnectionOptions`.
56
+
57
+ ## Connection & Authentication
58
+
59
+ `IKafkaProducerOptions`, `IKafkaConsumerOptions`, and `IKafkaAdminOptions` all extend `IKafkaConnectionOptions` - this section applies to all three.
60
+
61
+ | Option | Type | Default | Description |
62
+ |--------|------|---------|-------------|
63
+ | `bootstrapBrokers` | `string[]` | - | Broker addresses (`host:port`). **Required** |
64
+ | `clientId` | `string` | - | Unique client identifier. **Required** |
65
+ | `retries` | `number` | `3` | Connection retries before failing |
66
+ | `retryDelay` | `number` | `1000` | Delay between retries (ms) |
67
+ | `sasl` | `SASLOptions` | - | SASL authentication |
68
+ | `tls` / `ssl` | `TLSConnectionOptions` | - | TLS options (`ssl` is an alias for `tls`) |
69
+ | `connectTimeout` | `number` | - | TCP connection timeout (ms) |
70
+ | `requestTimeout` | `number` | - | Kafka request timeout (ms) |
71
+
72
+ **SASL mechanisms** (`@platformatic/kafka` supports five):
73
+
74
+ | Mechanism | Use case |
75
+ |-----------|----------|
76
+ | `PLAIN` | Username/password (pair with `tls` in production) |
77
+ | `SCRAM-SHA-256` / `SCRAM-SHA-512` | Challenge-response - password never sent in plaintext |
78
+ | `OAUTHBEARER` | Token-based - Azure Event Hubs, Confluent Cloud. `token` accepts a string or an async function that returns one |
79
+ | `GSSAPI` | Kerberos authentication |
48
80
 
49
- Plus all [Connection Options](./#connection-options).
81
+ ```typescript
82
+ import fs from 'node:fs';
83
+ import { KafkaProducerHelper } from '@venizia/ignis-helpers/kafka';
84
+
85
+ const producer = KafkaProducerHelper.newInstance({
86
+ bootstrapBrokers: ['broker1:9093', 'broker2:9093'],
87
+ clientId: 'order-producer',
88
+ sasl: { mechanism: 'SCRAM-SHA-512', username: 'kafka-user', password: 'kafka-password' },
89
+ tls: {
90
+ ca: fs.readFileSync('/path/to/ca.pem'),
91
+ cert: fs.readFileSync('/path/to/client-cert.pem'),
92
+ key: fs.readFileSync('/path/to/client-key.pem'),
93
+ },
94
+ connectTimeout: 30_000,
95
+ requestTimeout: 30_000,
96
+ });
97
+ ```
50
98
 
51
99
  ## Basic Example
52
100
 
@@ -92,6 +140,74 @@ await helper.close();
92
140
  await helper.close({ isForce: true });
93
141
  ```
94
142
 
143
+ ## Serialization
144
+
145
+ `@platformatic/kafka`'s default wire format is `Buffer`. The helpers default the generic types to `string`, but that's a type default only. Pass serializers explicitly, or messages travel as raw `Buffer`.
146
+
147
+ | Export | Type | Description |
148
+ |--------|------|-------------|
149
+ | `stringSerializer` / `stringDeserializer` | `Serializer<string>` / `Deserializer<string>` | UTF-8 string <-> `Buffer` |
150
+ | `jsonSerializer` / `jsonDeserializer` | `Serializer<T>` / `Deserializer<T>` | `JSON.stringify` / `JSON.parse` + UTF-8 |
151
+ | `stringSerializers` / `stringDeserializers` | `Serializers<string,string,string,string>` / `Deserializers<...>` | All four positions (key, value, header key, header value) as string |
152
+ | `serializersFrom(s)` / `deserializersFrom(d)` | `<T>(fn) => Serializers<T,T,T,T>` / `<T>(fn) => Deserializers<T,T,T,T>` | Build all four positions from a single serializer/deserializer |
153
+
154
+ ```typescript
155
+ import { stringSerializers } from '@platformatic/kafka';
156
+
157
+ const producer = KafkaProducerHelper.newInstance({
158
+ bootstrapBrokers: ['localhost:9092'],
159
+ clientId: 'my-producer',
160
+ serializers: stringSerializers,
161
+ });
162
+ ```
163
+
164
+ ```typescript
165
+ import { jsonSerializer, stringSerializer, serializersFrom } from '@platformatic/kafka';
166
+
167
+ const producer = KafkaProducerHelper.newInstance({
168
+ bootstrapBrokers: ['localhost:9092'],
169
+ clientId: 'my-producer',
170
+ serializers: { ...serializersFrom(jsonSerializer), key: stringSerializer },
171
+ });
172
+
173
+ await producer.getProducer().send({
174
+ messages: [{
175
+ topic: 'orders',
176
+ key: 'order-123',
177
+ value: { id: '123', status: 'created', amount: 99 },
178
+ }],
179
+ });
180
+ ```
181
+
182
+ For schema-validated serialization (Avro, Protobuf, JSON Schema), pass a `registry` instead of `serializers` - see [Schema Registry](./schema-registry).
183
+
184
+ ## Compression
185
+
186
+ `@platformatic/kafka` supports five compression algorithms:
187
+
188
+ | Algorithm | Value | Description |
189
+ |-----------|-------|-------------|
190
+ | None | `'none'` | No compression (default) |
191
+ | GZIP | `'gzip'` | Good compression ratio, moderate CPU |
192
+ | Snappy | `'snappy'` | Fast compression, moderate ratio |
193
+ | LZ4 | `'lz4'` | Very fast, good for high-throughput |
194
+ | Zstandard | `'zstd'` | Best ratio, moderate CPU |
195
+
196
+ ```typescript
197
+ const helper = KafkaProducerHelper.newInstance({
198
+ bootstrapBrokers: ['localhost:9092'],
199
+ clientId: 'my-producer',
200
+ serializers: stringSerializers,
201
+ compression: 'zstd',
202
+ });
203
+
204
+ // Override per-send
205
+ await helper.getProducer().send({
206
+ messages: [{ topic: 'logs', key: 'l1', value: largePayload }],
207
+ compression: 'lz4',
208
+ });
209
+ ```
210
+
95
211
  ## Transactions
96
212
 
97
213
  `runInTransaction()` wraps `beginTransaction()` -> callback -> `commit()` / `abort()` with automatic logging.
@@ -133,6 +249,8 @@ const result = await helper.runInTransaction(async ({ send, addConsumer, addOffs
133
249
  });
134
250
  ```
135
251
 
252
+ If the callback throws, the transaction is automatically aborted and the error re-thrown.
253
+
136
254
  ### Transaction Context
137
255
 
138
256
  The callback receives an `IKafkaTransactionContext`:
@@ -144,17 +262,17 @@ The callback receives an `IKafkaTransactionContext`:
144
262
  | `addConsumer(consumer)` | `(consumer: Consumer) => Promise<void>` | Add a consumer for exactly-once |
145
263
  | `addOffset(message)` | `(message: Message) => Promise<void>` | Add consumed message offset to transaction |
146
264
 
147
- If the callback throws, the transaction is automatically aborted and the error re-thrown.
148
-
149
265
  ## Graceful Shutdown
150
266
 
151
- `close()` implements a two-phase shutdown:
267
+ `close()` runs a two-phase shutdown:
152
268
 
153
- 1. **Graceful** (default): Calls `close(true)` on the underlying producer (force-flush), with a timeout (`shutdownTimeout`, default 30s)
154
- 2. **Force fallback**: If graceful times out, automatically force-closes
155
- 3. **Force** (`{ isForce: true }`): Immediately calls `close(true)` without timeout protection
269
+ | Phase | When it runs | What happens |
270
+ |---|---|---|
271
+ | Graceful | Default | Calls `close(true)` on the underlying producer, capped at `shutdownTimeout` (default 30s) |
272
+ | Force fallback | Graceful times out | Force-closes automatically, no further waiting |
273
+ | Force | `close({ isForce: true })` | Calls `close(true)` immediately, no timeout |
156
274
 
157
- After `close()`, all broker tracking is cleared and `healthStatus` is set to `'disconnected'`.
275
+ After `close()`, all broker tracking is cleared and `healthStatus` becomes `'disconnected'`.
158
276
 
159
277
  ```typescript
160
278
  // Graceful (recommended)
@@ -166,7 +284,7 @@ await helper.close({ isForce: true });
166
284
 
167
285
  ## API Reference (`@platformatic/kafka`)
168
286
 
169
- After calling `helper.getProducer()`, you have full access to the `Producer` class:
287
+ After calling `helper.getProducer()`, you have full access to the `Producer` class.
170
288
 
171
289
  ### `producer.send(options)`
172
290
 
@@ -257,11 +375,13 @@ Close the producer connection.
257
375
 
258
376
  ## Key Partitioning
259
377
 
260
- By default, `@platformatic/kafka` uses **murmur2 hashing** on the message key to determine the target partition:
378
+ By default, `@platformatic/kafka` uses **murmur2 hashing** on the message key to pick the target partition:
261
379
 
262
- - Same key -> always same partition -> guaranteed ordering per key
263
- - `undefined` key -> round-robin across partitions
264
- - Explicit `partition` field -> overrides the partitioner
380
+ | Key | Target partition |
381
+ |---|---|
382
+ | Same key, every time | Same partition - ordering is guaranteed per key |
383
+ | `undefined` | Round-robin across partitions |
384
+ | Explicit `partition` field | That partition, overriding the partitioner |
265
385
 
266
386
  ```typescript
267
387
  // Custom partitioner
@@ -272,3 +392,17 @@ await producer.send({
272
392
  },
273
393
  });
274
394
  ```
395
+
396
+ ## See also
397
+
398
+ - [Kafka Overview](./) - the four helpers, shared health/close API, and the compile-binary caveat
399
+ - [Consumer](./consumer) - the receiving side, including message callbacks and lag monitoring
400
+ - [Schema Registry](./schema-registry) - schema-validated serialization instead of manual `serializers`
401
+ - [Compiling to a Single Binary](./compile-binary) - required when this helper ships inside a `bun build --compile` binary
402
+ - [Examples & Troubleshooting](./examples) - IoC wiring and the common connection-error lookup table
403
+
404
+ **Files:**
405
+
406
+ - [`packages/helpers/src/modules/queue/kafka/producer.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/producer.ts) - `KafkaProducerHelper`
407
+ - [`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`, shared health tracking and shutdown
408
+ - [`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) - `IKafkaProducerOptions`, `IKafkaConnectionOptions`, `IKafkaTransactionContext`
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: Kafka Schema Registry
3
+ description: KafkaSchemaRegistryHelper - schema-validated serialization for Avro, Protobuf, and JSON Schema
4
+ difficulty: intermediate
5
+ ---
6
+
1
7
  # Schema Registry
2
8
 
3
9
  The `KafkaSchemaRegistryHelper` wraps `@platformatic/kafka`'s `ConfluentSchemaRegistry`. It provides a centralized schema registry that auto-serializes/deserializes messages using registered schemas (Avro, Protobuf, JSON Schema).
@@ -12,7 +18,10 @@ class KafkaSchemaRegistryHelper<
12
18
  ```
13
19
 
14
20
  > [!NOTE]
15
- > `KafkaSchemaRegistryHelper` extends `BaseHelper` directly (not `BaseKafkaHelper`) -- it has no broker connection or health tracking. It's a configuration wrapper, not a client.
21
+ > `KafkaSchemaRegistryHelper` extends `BaseHelper` directly (not `BaseKafkaHelper`) - it has no broker connection or health tracking. It's a configuration wrapper, not a client.
22
+
23
+ > [!WARNING]
24
+ > Compiling to a standalone binary needs `platformaticRequirePlugin()`. `ConfluentSchemaRegistry` resolves `ajv-draft-04` through `createRequire` at module load, which `bun build --compile` cannot see through. See [Compiling to a Single Binary](./compile-binary).
16
25
 
17
26
  ## Helper API
18
27
 
@@ -33,27 +42,35 @@ interface IKafkaSchemaRegistryOptions extends ConfluentSchemaRegistryOptions {
33
42
 
34
43
  | Option | Type | Default | Description |
35
44
  |--------|------|---------|-------------|
36
- | `url` | `string` | -- | Schema registry URL. **Required** |
37
- | `auth` | `{ username: string; password: string }` | -- | Basic auth credentials |
38
- | `protobufTypeMapper` | `ProtobufTypeMapper` | -- | Custom Protobuf type mapper |
39
- | `jsonValidateSend` | `boolean` | -- | Validate JSON schema on produce |
45
+ | `url` | `string` | - | Schema registry URL. **Required** |
46
+ | `auth` | `{ username: string; password: string }` | - | Basic auth credentials |
47
+ | `protobufTypeMapper` | `ProtobufTypeMapper` | - | Custom Protobuf type mapper |
48
+ | `jsonValidateSend` | `boolean` | - | Validate JSON schema on produce |
40
49
  | `identifier` | `string` | `'kafka-schema-registry'` | Scoped logging identifier |
41
50
 
42
- ## What Schema Registry Solves
51
+ ## What it solves
43
52
 
44
- Without a schema registry, producers and consumers must agree on message format out-of-band. If the producer changes the shape of `value` (adds/removes fields), consumers break silently at runtime.
53
+ Without a schema registry, producers and consumers must agree on message shape out-of-band. If the producer changes the shape of `value` (adds/removes fields), consumers break silently at runtime.
45
54
 
46
- **Schema Registry** is a centralized server (Confluent Schema Registry) that stores and validates schemas (Avro, Protobuf, JSON Schema). It enforces a contract:
55
+ - **Schema Registry is a centralized server** (Confluent Schema Registry) that stores and validates schemas.
56
+ - **It enforces a contract on the way out.** The producer says "I want to send this shape." The registry validates that shape against the registered schema before the message reaches Kafka.
57
+ - **It enforces a contract on the way in.** The consumer asks "what shape is this?" The registry answers with how to deserialize it.
47
58
 
48
- ```
49
- Producer -> "I want to send this shape" -> Schema Registry validates -> Kafka
50
- Kafka -> Consumer -> "What shape is this?" -> Schema Registry tells -> Deserialize
51
- ```
59
+ | | Without registry | With registry |
60
+ |---|---|---|
61
+ | **Message format** | Raw string, manual `JSON.stringify`/`JSON.parse` | Typed object, auto ser/deser |
62
+ | **Validation** | None - runtime crashes on shape drift | Schema validated before send |
63
+ | **Schema evolution** | Breaks consumers silently | Backward/forward compatibility enforced |
64
+ | **Where schemas live** | Nowhere (tribal knowledge) | Centralized server, e.g. `http://registry:8081` |
65
+
66
+ Use it when you need schema enforcement and compatibility checks across producers and consumers, especially in multi-team environments. Skip it for simple string or JSON messages where one team controls both sides - coordinate format changes by hand instead.
52
67
 
53
- ### Without Schema Registry (raw strings)
68
+ ## Without vs. with the registry
69
+
70
+ Without a registry, serialization is entirely manual and unchecked:
54
71
 
55
72
  ```typescript
56
- // Producer -- manually serialize
73
+ // Producer - manually serialize
57
74
  const producer = KafkaProducerHelper.newInstance({
58
75
  bootstrapBrokers: ['127.0.0.1:29092'],
59
76
  clientId: 'order-producer',
@@ -63,11 +80,11 @@ await producer.getProducer().send({
63
80
  messages: [{
64
81
  topic: 'orders',
65
82
  key: 'order-1',
66
- value: JSON.stringify({ id: 1, total: 99.99 }), // <- just a string, no validation
83
+ value: JSON.stringify({ id: 1, total: 99.99 }), // <- plain string, no validation
67
84
  }],
68
85
  });
69
86
 
70
- // Consumer -- manually deserialize, hope the shape is correct
87
+ // Consumer - manually deserialize, hope the shape is correct
71
88
  const consumer = KafkaConsumerHelper.newInstance({
72
89
  bootstrapBrokers: ['127.0.0.1:29092'],
73
90
  clientId: 'order-consumer',
@@ -79,22 +96,28 @@ const consumer = KafkaConsumerHelper.newInstance({
79
96
  });
80
97
  ```
81
98
 
82
- Problem: if producer adds `{ id: 1, total: 99.99, currency: 'USD' }` or removes `total`, consumer has no way to know until it crashes.
99
+ If the producer adds `{ id: 1, total: 99.99, currency: 'USD' }` or removes `total`, the consumer has no way to know until it crashes.
83
100
 
84
- ### With Schema Registry (auto serialize/deserialize)
101
+ With a registry, both sides pass `registry` instead of `serializers`/`deserializers`:
85
102
 
86
103
  ```typescript
87
- // 1. Create registry -- points to Confluent Schema Registry server
104
+ import {
105
+ KafkaSchemaRegistryHelper,
106
+ KafkaProducerHelper,
107
+ KafkaConsumerHelper,
108
+ } from '@venizia/ignis-helpers/kafka';
109
+
110
+ // 1. Create registry - points to Confluent Schema Registry server
88
111
  const registry = KafkaSchemaRegistryHelper.newInstance({
89
112
  url: 'http://localhost:8081',
90
113
  // auth: { username: 'user', password: 'pass' }, // optional
91
114
  });
92
115
 
93
- // 2. Producer -- pass registry, it auto-serializes values using registered schema
116
+ // 2. Producer - pass registry, it auto-serializes values using the registered schema
94
117
  const producer = KafkaProducerHelper.newInstance({
95
118
  bootstrapBrokers: ['127.0.0.1:29092'],
96
119
  clientId: 'order-producer',
97
- registry: registry.getRegistry(), // <- registry handles serialization
120
+ registry: registry.getRegistry(),
98
121
  });
99
122
 
100
123
  await producer.getProducer().send({
@@ -106,61 +129,11 @@ await producer.getProducer().send({
106
129
  });
107
130
  // If the value doesn't match the registered schema -> error BEFORE sending to Kafka
108
131
 
109
- // 3. Consumer -- pass same registry, it auto-deserializes
132
+ // 3. Consumer - pass the same registry, it auto-deserializes
110
133
  const consumer = KafkaConsumerHelper.newInstance({
111
134
  bootstrapBrokers: ['127.0.0.1:29092'],
112
135
  clientId: 'order-consumer',
113
136
  groupId: 'order-group',
114
- registry: registry.getRegistry(), // <- registry handles deserialization
115
- onMessage: async ({ message }) => {
116
- // message.value is already a typed object, not a raw string
117
- console.log(message.value.id, message.value.total);
118
- },
119
- });
120
- ```
121
-
122
- ### Comparison
123
-
124
- | | Without Registry | With Registry |
125
- |---|---|---|
126
- | **Message format** | Raw string, manual `JSON.stringify/parse` | Typed object, auto ser/deser |
127
- | **Validation** | None -- runtime crashes | Schema validated before send |
128
- | **Schema evolution** | Break consumers silently | Backward/forward compatibility enforced |
129
- | **Where schemas live** | Nowhere (tribal knowledge) | Centralized server `http://registry:8081` |
130
-
131
- You only need it when you want **schema enforcement** across producers/consumers. For simple string messages, skip it entirely.
132
-
133
- ## Basic Usage
134
-
135
- ```typescript
136
- import { KafkaSchemaRegistryHelper, KafkaProducerHelper, KafkaConsumerHelper } from '@venizia/ignis-helpers/kafka';
137
-
138
- // 1. Create registry -- points to Confluent Schema Registry server
139
- const registry = KafkaSchemaRegistryHelper.newInstance({
140
- url: 'http://localhost:8081',
141
- });
142
-
143
- // 2. Producer -- registry auto-serializes values using registered schema
144
- const producer = KafkaProducerHelper.newInstance({
145
- bootstrapBrokers: ['localhost:9092'],
146
- clientId: 'order-producer',
147
- registry: registry.getRegistry(),
148
- });
149
-
150
- await producer.getProducer().send({
151
- messages: [{
152
- topic: 'orders',
153
- key: 'order-1',
154
- value: { id: 1, total: 99.99 }, // object, not string -- registry serializes
155
- }],
156
- });
157
- // If value doesn't match the registered schema -> error BEFORE sending to Kafka
158
-
159
- // 3. Consumer -- registry auto-deserializes
160
- const consumer = KafkaConsumerHelper.newInstance({
161
- bootstrapBrokers: ['localhost:9092'],
162
- clientId: 'order-consumer',
163
- groupId: 'order-group',
164
137
  registry: registry.getRegistry(),
165
138
  onMessage: async ({ message }) => {
166
139
  // message.value is already a typed object, not a raw string
@@ -171,7 +144,7 @@ const consumer = KafkaConsumerHelper.newInstance({
171
144
  await consumer.start({ topics: ['orders'] });
172
145
  ```
173
146
 
174
- ## With Authentication
147
+ ## With authentication
175
148
 
176
149
  ```typescript
177
150
  const registry = KafkaSchemaRegistryHelper.newInstance({
@@ -183,9 +156,9 @@ const registry = KafkaSchemaRegistryHelper.newInstance({
183
156
  });
184
157
  ```
185
158
 
186
- ## Alternative: Manual Serializers
159
+ ## Alternative: manual serializers
187
160
 
188
- Instead of passing the full registry, you can extract serializers/deserializers for manual use:
161
+ Instead of passing the full registry to `registry`, extract serializers/deserializers for manual use alongside `serializers`/`deserializers`:
189
162
 
190
163
  ```typescript
191
164
  const registry = KafkaSchemaRegistryHelper.newInstance({
@@ -204,11 +177,18 @@ const consumer = KafkaConsumerHelper.newInstance({
204
177
  clientId: 'my-consumer',
205
178
  groupId: 'my-group',
206
179
  deserializers: registry.getDeserializers(),
207
- onMessage: async ({ message }) => { ... },
180
+ onMessage: async ({ message }) => { /* ... */ },
208
181
  });
209
182
  ```
210
183
 
211
- ## When to Use
184
+ ## See also
185
+
186
+ - [Kafka Overview](./) - the four helpers, shared health/close API, and the compile-binary caveat
187
+ - [Producer](./producer) - `registry` as a producer option, plus the manual `serializers` alternative
188
+ - [Consumer](./consumer) - `registry` as a consumer option, plus the manual `deserializers` alternative
189
+ - [Examples & Troubleshooting](./examples) - IoC wiring and the common connection-error lookup table
190
+
191
+ **Files:**
212
192
 
213
- - **Use schema registry** when you need schema enforcement, validation, and compatibility checks across producers/consumers -- especially in multi-team environments
214
- - **Skip schema registry** for simple string/JSON messages where both sides are controlled by the same team and format changes are coordinated
193
+ - [`packages/helpers/src/modules/queue/kafka/schema/registry.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/schema/registry.ts) - `KafkaSchemaRegistryHelper`
194
+ - [`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) - `IKafkaSchemaRegistryOptions`