Current section
Files
Jump to
Current section
Files
usage-rules.md
# Kayrock Usage Rules
Kayrock is an Elixir library for Kafka protocol serialization and deserialization.
It generates Elixir structs from Kafka protocol schemas.
## Critical: The Built-in Client is NOT Production-Ready
The `Kayrock.Client` module and convenience functions like `Kayrock.produce/5` and
`Kayrock.fetch/5` are for **development and testing only**.
### DON'T use in production:
```elixir
# DON'T - Not production-ready
{:ok, client} = Kayrock.Client.start_link([{"localhost", 9092}])
Kayrock.produce(client, batch, "topic", 0)
```
### DO use Kayrock for serialization with a production client:
```elixir
# DO - Use with KafkaEx or brod
request = %Kayrock.Produce.V3.Request{
acks: -1,
timeout: 5000,
topic_data: [%{topic: "my-topic", data: [...]}]
}
wire_data = Kayrock.Request.serialize(request)
# Send via KafkaEx or brod connection
```
## Struct Naming Convention
All generated structs follow this pattern:
```
Kayrock.<API>.V<version>.<Request|Response>
```
Examples:
- `Kayrock.Produce.V1.Request` - Produce API version 1 request
- `Kayrock.Fetch.V4.Response` - Fetch API version 4 response
- `Kayrock.Metadata.V1.Request` - Metadata API version 1 request
## Compression Dependencies
Compression support requires optional dependencies. Without them, you'll get runtime errors.
### Available compression formats:
| Format | Attribute | Dependency |
|-----------|-----------|-------------------------|
| None | 0 | Built-in |
| Gzip | 1 | Built-in |
| Snappy | 2 | `{:snappyer, "~> 1.2"}` |
| LZ4 | 3 | `{:lz4b, "~> 0.0.13"}` |
| Zstandard | 4 | `{:ezstd, "~> 1.0"}` |
### Add to mix.exs if using compression:
```elixir
{:snappyer, "~> 1.2"}, # For Snappy
{:lz4b, "~> 0.0.13"}, # For LZ4
{:ezstd, "~> 1.0"}, # For Zstandard
```
## Creating Record Batches
Use `Kayrock.RecordBatch` for modern Kafka (0.11+):
```elixir
batch = %Kayrock.RecordBatch{
attributes: 0, # 0=none, 1=gzip, 2=snappy, 3=lz4, 4=zstd
records: [
%Kayrock.RecordBatch.Record{
key: "my-key",
value: "my-value",
headers: [{"header-name", "header-value"}]
}
]
}
```
## Serialization and Deserialization
### Serialize a request:
```elixir
request = %Kayrock.Metadata.V1.Request{
correlation_id: 1,
client_id: "my_app",
topics: [%{name: "my-topic"}]
}
# Returns iodata (efficient for network)
wire_data = Kayrock.Request.serialize(request)
```
### Deserialize a response:
```elixir
# Get the deserializer for a request
deserializer = Kayrock.Request.response_deserializer(request)
# Parse binary response
{response, _rest} = deserializer.(binary_response)
```
## API Version Selection
Different Kafka versions support different API versions. Always check broker compatibility.
### Produce API versions:
| Version | Min Kafka | Features |
|-----------|-------------|---------------------|
| V0-V2 | 0.9 | Basic produce |
| V3 | 0.11 | Idempotent producer |
| V7 | 2.1 | Transaction support |
### Fetch API versions:
| Version | Min Kafka | Features |
|-----------|------------|-----------------|
| V0-V3 | 0.9 | Basic fetch |
| V4 | 0.11 | Isolation level |
| V7 | 1.1 | Session fetch |
## Error Handling
Kafka errors are returned in response structs, not as exceptions.
```elixir
case response do
%{error_code: 0} ->
# Success
:ok
%{error_code: error_code} ->
# Use Kayrock.ErrorCode to decode
error_name = Kayrock.ErrorCode.code_to_atom(error_code)
{:error, error_name}
end
```
## Common Mistakes to Avoid
1. **Don't use the built-in client in production** - Use KafkaEx or brod
2. **Don't forget compression dependencies** - They're optional, add what you need
3. **Don't hardcode API versions** - Check broker capabilities with ApiVersions
4. **Don't ignore error_code in responses** - Kafka returns errors in the response
5. **Don't assume message ordering** - Use partition keys for ordering guarantees
## Working with Multiple Partitions
```elixir
# Produce to specific partition
request = %Kayrock.Produce.V1.Request{
topic_data: [
%{
topic: "my-topic",
data: [
%{partition: 0, record_set: batch_for_partition_0},
%{partition: 1, record_set: batch_for_partition_1}
]
}
]
}
```
## Quick Reference
### Check broker API versions:
```elixir
request = %Kayrock.ApiVersions.V1.Request{correlation_id: 1, client_id: "my_app"}
```
### Fetch topic metadata:
```elixir
request = %Kayrock.Metadata.V1.Request{
correlation_id: 1,
client_id: "my_app",
topics: [%{name: "my-topic"}] # or nil for all topics
}
```
### Create topics:
```elixir
request = %Kayrock.CreateTopics.V2.Request{
correlation_id: 1,
client_id: "my_app",
create_topic_requests: [
%{
topic: "new-topic",
num_partitions: 3,
replication_factor: 1,
replica_assignment: [],
config_entries: []
}
],
timeout: 30_000
}
```