Skip to content

feat(sink): support dynamic URL for HTTP sink - #25699

Merged
wenym1 merged 5 commits into
mainfrom
wenym1/check-turbopuffer-rust-sdk
May 21, 2026
Merged

wenym1 merged 5 commits into
mainfrom
wenym1/check-turbopuffer-rust-sdk

Conversation

@wenym1

@wenym1 wenym1 commented May 18, 2026 •

Copy link
Copy Markdown
Contributor

I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.

What's changed and what's your intention?

This PR extends the HTTP sink so its target URL can be supplied by the sink row itself.

  • Keeps the existing single-column HTTP sink behavior unchanged: one varchar or jsonb payload column with WITH (url = ...).
  • Adds a multi-column shape for dynamic targets:
    • required payload column of type varchar or jsonb
    • optional url column of type varchar
  • Requires exactly one target URL source for multi-column sinks: either the static url option or the dynamic url column.
  • Stores static URLs as parsed reqwest::Url, and parses dynamic row URLs before sending each request.
  • Adds SQLLogicTest coverage for validation paths, dynamic URL sinks, and CREATE SINK AS SELECT.

Example SQL:

CREATE TABLE http_events (
    payload JSONB,
    url VARCHAR
);

CREATE SINK dynamic_http_sink FROM http_events WITH (
    connector = 'http',
    type = 'append-only',
    force_append_only = 'true'
);

INSERT INTO http_events VALUES
    ('{"event":"upsert","id":1}'::jsonb, 'https://example.com/workspace-a/events'),
    ('{"event":"upsert","id":2}'::jsonb, 'https://example.com/workspace-b/events');

For CREATE SINK AS SELECT, project the payload and URL columns with the required output names:

CREATE SINK dynamic_http_sink AS
SELECT
    event_body AS payload,
    format('https://example.com/workspaces/%s/events', workspace_id) AS url
FROM source_events
WITH (
    connector = 'http',
    type = 'append-only',
    force_append_only = 'true'
);
  • Closes #N/A

Checklist

  • I have written necessary rustdoc comments.
  • I have added necessary unit tests and integration tests.
  • I have added test labels as necessary.
  • I have added fuzzing tests or opened an issue to track them.
  • My PR contains breaking changes.
  • My PR changes performance-critical code, so I will run (micro) benchmarks and present the results.
  • I have checked the Release Timeline and Currently Supported Versions to determine which release branches I need to cherry-pick this PR into.

Documentation

  • My PR needs documentation updates.
Release note

HTTP sinks can now derive the target URL from a row column by outputting payload and url columns, enabling dynamic per-row HTTP destinations while preserving the existing static URL behavior.

Allow HTTP sinks to derive the target URL from a row column when the sink output schema contains payload and url columns. Keep the existing single-column static URL behavior unchanged.

wenym1 commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions Bot added the A-ci Area: CI workflow and scripts, etc. label May 18, 2026
@wenym1 wenym1 changed the title ci: use CI token for bump main PRs (#25683) feat(sink): support dynamic URL for HTTP sink May 18, 2026
@wenym1 wenym1 added type/feature Type: New feature. A-connector Area: Connector. user-facing-changes Contains changes that are visible to users ci/run-e2e-sink-tests labels May 18, 2026
@wenym1
wenym1 marked this pull request as ready for review May 18, 2026 09:50
@wenym1
wenym1 requested review from hzxa21 and xxhZs May 18, 2026 09:58
@yuhao-su

Copy link
Copy Markdown
Contributor

How to tell the difference between use url as a dynamic url or a field when sinking

@wenym1

wenym1 commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

How to tell the difference between use url as a dynamic url or a field when sinking

The http payload is in a single column, either jsonb or text. When the sink has only a single column, this column is the payload column. When the sink has multiple column, we check the name of each column, to be either payload and url.

@wenym1
wenym1 requested a review from yuhao-su May 18, 2026 16:37
Comment thread src/connector/src/sink/http.rs Outdated

@hzxa21 hzxa21 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a comment about log DDoS. You can merge the PR first and create follow-up issue on that you would like to provide a preview image for trial usage first.

Rest LGTM.

Comment on lines +293 to +306
tracing::warn!(
error = %err.as_report(),
payload = %self.strip_payload_for_log(row),
"skip HTTP sink row due to invalid URL in url column"
);
Ok(None)
}
}
}
Some(ScalarRefImpl::Utf8(_)) | None => {
tracing::warn!(
payload = %self.strip_payload_for_log(row),
"skip HTTP sink row due to null or empty url column"
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about implementing some kind of a log suppressor to avoid log DDoS when there are many invalid URLs in the payload?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will integrate it to sink dead letter queue when it's implemented.

@wenym1
wenym1 added this pull request to the merge queue May 21, 2026
Merged via the queue into main with commit d95a087 May 21, 2026
36 of 37 checks passed
@wenym1
wenym1 deleted the wenym1/check-turbopuffer-rust-sdk branch May 21, 2026 17:52
cyberchen98 added a commit that referenced this pull request Jun 2, 2026
…#25889)

Co-authored-by: William Wen <44139337+wenym1@users.noreply.github.com>
Co-authored-by: congyi wang <58715567+wcy-fdu@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

✅ Cherry-pick PRs (or issues if encountered conflicts) have been created successfully to all target branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ci Area: CI workflow and scripts, etc. A-connector Area: Connector. ci/run-e2e-sink-tests need-cherry-pick-since-release-2.8 type/feature Type: New feature. user-facing-changes Contains changes that are visible to users

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants