You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature idea: Per-message HTTP header forwarding in sink connectors
#65
Context: While working on the HTTP sink PR (apache/iggy#2925), a question came up about dynamic per-message headers. Today, all HTTP headers are static (config-derived, same for every request). But there are real use cases for per-message headers.
Use cases
X-Iggy-Offset / X-Iggy-Topic / X-Iggy-Partition — routing and dedup at the HTTP endpoint without body parsing
Forwarding Iggy user-defined message headers (ConsumedMessage.headers) as HTTP headers — e.g., a producer attaches X-Correlation-ID and the sink forwards it to the downstream endpoint
Proposed design — additive layering
// Static config headers (pre-built once in open(), cloned per-request)letmut request = build_request(self.method, client,&self.url).headers(self.request_headers.clone()).header("content-type", content_type);// Per-message dynamic headers (opt-in via config)ifself.include_metadata_headers{
request = request
.header("x-iggy-offset", offset.to_string()).header("x-iggy-topic",&topic_metadata.topic).header("x-iggy-partition", partition_id.to_string());}// Forward Iggy user headers as HTTP headers (opt-in)ifself.forward_iggy_headers{ifletSome(headers) = &message.headers{for(key, value)in headers {
request = request.header(format!("x-iggy-{}", key.to_string_value()),
value.to_string_value(),);}}}
Config surface
[plugin_config]
# Include iggy metadata (offset, topic, partition) as HTTP headersinclude_metadata_headers = false# Forward iggy user-defined message headers as HTTP headers (prefixed with x-iggy-)forward_iggy_headers = false
This preserves the current pre-built HeaderMap optimization for static headers while layering dynamic per-message headers on top. Both options are opt-in and disabled by default.
Design considerations
Batch modes: For ndjson and json_array, per-message headers only apply if the batch contains a single message, or we'd need to pick "representative" headers from the batch (e.g., first message, or common subset). For individual mode it's straightforward — each message is its own HTTP request.
Header name conflicts: If a user-defined Iggy header name conflicts with a static config header, the static header should win (config is explicit intent). Alternatively, we could log a warning.
Performance: Adding per-message headers is a few string allocations per request. For individual mode at high throughput this could add up, but it's behind an opt-in flag so the default path is unchanged.
This could be a follow-up PR after the base HTTP sink (apache/iggy#2925) lands. Thoughts?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Feature idea: Per-message HTTP header forwarding
Moved from discussion #2919 at @hubcio's request.
Context: While working on the HTTP sink PR (apache/iggy#2925), a question came up about dynamic per-message headers. Today, all HTTP headers are static (config-derived, same for every request). But there are real use cases for per-message headers.
Use cases
X-Iggy-Offset/X-Iggy-Topic/X-Iggy-Partition— routing and dedup at the HTTP endpoint without body parsingConsumedMessage.headers) as HTTP headers — e.g., a producer attachesX-Correlation-IDand the sink forwards it to the downstream endpointProposed design — additive layering
Config surface
This preserves the current pre-built
HeaderMapoptimization for static headers while layering dynamic per-message headers on top. Both options are opt-in and disabled by default.Design considerations
ndjsonandjson_array, per-message headers only apply if the batch contains a single message, or we'd need to pick "representative" headers from the batch (e.g., first message, or common subset). Forindividualmode it's straightforward — each message is its own HTTP request.individualmode at high throughput this could add up, but it's behind an opt-in flag so the default path is unchanged.This could be a follow-up PR after the base HTTP sink (apache/iggy#2925) lands. Thoughts?
All reactions