Skip to content

feat: add a per-route test-request drawer with a copyable curl - #3456

Merged
LiteSun merged 1 commit into
apache:masterfrom
lxbme:feat/route-test-request
Aug 3, 2026
Merged

LiteSun merged 1 commit into
apache:masterfrom
lxbme:feat/route-test-request

Conversation

@lxbme

@lxbme lxbme commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Please answer these questions before submitting a pull request, or your PR will get closed.

Why submit this pull request?

  • Bugfix
  • New feature provided
  • Improve performance
  • Backport patches

What changes will this PR take into?

Configuration happens on the admin port; verification happens on the data plane port. The dashboard covered the first and said nothing about the second, so confirming that a route you had just created actually serves traffic meant leaving the UI and hand-writing a curl.

A route's detail page now has a Test button opening a request drawer.

It prefills from the route's own config — the method (constrained to the methods the route declares), the path, and a Host header when the route matches on host. A wildcard or regex uri comes through verbatim with a hint to replace it with a concrete path.

The equivalent curl is always visible and recomputes as you edit any field, with a copy button. Until a gateway URL is entered the base renders as http://<gateway-host>:<port> so the command is still copyable and completable by hand. The gateway URL is remembered in localStorage, drawer-local — no new app-wide setting.

Sending is best-effort and degrades honestly. Two constraints shape this and are worth stating, because they rule out the obvious approach: the data plane is a different origin and sends no CORS headers by default, so the browser usually cannot read the response; and fetch is not permitted to set the Host header, so a host-matched route cannot be reproduced from the browser even when it is reachable. The generated command is therefore the dependable path. A send that the browser cannot read resolves to one explicit message — "the browser couldn't read a response (likely cross-origin or unreachable), copy the command above and run it in a terminal" — rather than a misleading failure. When the response is readable, the drawer shows the status coloured by class, the elapsed time, a collapsible header list, and a pretty-printed body.

Showing the equivalent curl also has value beyond testing: it makes the Admin API legible and gives users a path from clicking to scripting.

Scope is HTTP routes. A superseded in-flight send cannot paint over a newer request: each send carries a token that is checked before any state is written, and closing the drawer invalidates whatever is in flight.

Rebased onto the merged sibling PRs

This branch now sits on master with #3454, #3457, #3458 and #3459 merged. The only conflict was in src/routes/routes/detail.$id.tsx, where #3458 rewrote the same PageHeader block this PR adds the Test button to. Resolved by keeping both: extra renders unconditionally so Test is available in either mode, Edit and Delete stay inside the read-only branch, and the title keeps #3458's id-bearing info.detail.titleWithId rather than the older string this branch was written against. All five locale files merged automatically.

Related issues

Part of #3453

Checklist:

  • Did you explain what problem does this PR solve? Or what new features have been added?
  • Have you added corresponding test cases?
  • Have you modified the corresponding document?
  • Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first

Tests: util.test.ts covers the prefill rules and the curl rendering, with the shell-escaping of single quotes in URLs, header values and bodies as its focus. sendLive.test.ts covers both outcomes against a mocked fetch. e2e/tests/regression/routes.test-request-drawer.spec.ts seeds a route with the mocking plugin, then asserts the prefilled curl, that editing the path updates it live, that Copy reports success, and that an unreachable gateway produces the honest fallback — the deterministic branch, since cross-origin has a predictable outcome.

Verified: pnpm test, pnpm lint, pnpm exec tsc -b and a production pnpm build all clean; the full pnpm e2e suite green apart from pre-existing environment flakes that pass on isolated rerun. Checked by hand in Chrome on both paths — with the cors plugin on the route the drawer renders a real 200 OK with timing and body; without it, the fallback message.

Configuration happens on the admin port; verification happens on the data
plane port. The dashboard covered the first and said nothing about the
second, so confirming that a route you had just created actually serves
traffic meant leaving the UI and hand-writing a curl.

A route's detail page now has a Test button opening a request drawer. It
prefills from the route's own config — the method, the path, and a Host
header when the route matches on host — and always shows the equivalent
curl, recomputed as you edit and ready to copy.

Sending is best-effort and degrades honestly. Two constraints rule out the
obvious approach: the data plane is a different origin and sends no CORS
headers by default, so the browser usually cannot read the response, and
fetch may not set the Host header, so a host-matched route cannot be
reproduced from the browser even when it is reachable. The generated
command is therefore the dependable path, and a send the browser cannot
read resolves to one explicit message rather than a misleading failure.

Showing the equivalent curl also makes the Admin API legible and gives
users a path from clicking to scripting.

Part of apache#3453
@lxbme
lxbme force-pushed the feat/route-test-request branch from 5e69e17 to 78cfc49 Compare August 3, 2026 01:51
@lxbme
lxbme marked this pull request as ready for review August 3, 2026 01:57
@LiteSun
LiteSun merged commit 836f6b1 into apache:master Aug 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants