2 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 3011b92ea4 routing: one router, and it is zip
gorilla/mux, otelmux, gorilla/handlers and rs/cors leave go.mod. Every route
the runtime serves is a zip route on a zip group: 233 from the apiserver tree,
134 from query-service, 367 total — the same 367 the mount publishes.

pkg/http/routing is the one registration surface. It exists because a
registration carries three facts zip has no slot for, and the tree this
replaces recovered all three PER REQUEST by asking the router what it had just
matched: the bound segments, the path template, and the route's declared
resources. mux.CurrentRoute(req).GetHandler() was type-asserted back to
handler.Handler in two separate packages to re-derive at request time what was
already known once at boot. Stating them at registration deletes both lookups.

The middleware chain is composed at the LEAF rather than registered ambient,
because Audit keys on the route template and Resource resolves the route's
declared resources — ambient middleware runs before the router has matched, so
both would read an empty route. Per-leaf composition reproduces the order the
old tree ran in exactly: match, then middleware, then handler.

Duplicate registration now panics at boot; gorilla let the first one win.
The Sentry ingest constraint becomes fiber's own guid — a UUID parse instead of
a hand-written character class. Paths keep their public brace spelling in the
source and in the table; the respelling happens in one function.

The standalone server hands its listener to the app, so streams and the
websocket upgrade run native fasthttp.

Counted, not asserted: routes_test.go in the apiserver pins 233 against the
real AddToRouter, routing_test.go pins the table against the router itself.
This repo has already shipped 83 typed ops that reached no router while the
suite stayed green — an uncalled func is legal Go, so arithmetic is the test.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 19:30:40 -07:00
zeekayandHanzo Dev 20ec5d62ea routing: query service and gateway read a path segment, not gorilla's map
19 reads across three files stop naming gorilla to address a resource by id and
go through coretypes.Param: 13 in the query-service handler (rule id, integration
id, pipeline version, six funnel ids), 1 in the parser (trace id), 5 in the
gateway (key id, limit id). Registration is untouched — this is the read side.

Where a site had bound `vars := mux.Vars(r)` only to index it once, the map is
gone with it; a handler wants the VALUE, and keeping a map alive to hold one
string was the router leaking into the body.

The query half stays exactly where it was. ParseSearchTracesParams now reads the
trace id from the PATH and the span id from the QUERY through two different
calls, which is what they always were.

http_handler.go keeps `mux.NewRouter().UseEncodedPath()` and the websocket
upgrader: those are the internal tree and its transport, converted as one piece
with the other 70 registration files, not here.

parser.go drops the gorilla import entirely; gateway/handler.go likewise.

Tests: neither package had one that exercised a path segment, so both go green
whether the read works or not — this repo has already shipped that defect. Each
now drives a REAL router registered at the REAL template. The gateway rows go
router -> handler -> Gateway and assert the id the gateway was HANDED, so an
empty segment fails on the recorded value rather than on a status code. Under a
Param that returns "", all four tests go red; before them, both packages stayed
green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:53:20 -07:00