fix(apiv3): Accept camelCase HTTP query params, keep snake_case as deprecated aliases#8625
Conversation
…precated aliases Part 2 of jaegertracing#8619. Moves query param constants and parsing logic into a new query_parser.go. Canonical param names are now camelCase (e.g. query.serviceName, startTime, spanKind) matching proto3 JSON encoding; snake_case names remain accepted as deprecated fallbacks via a getQueryParam helper. Signed-off-by: Yuri Shkuro <github@ysh.us>
There was a problem hiding this comment.
Pull request overview
This PR updates the APIv3 HTTP gateway query parameter parsing to accept canonical camelCase parameter names (aligned with proto3 JSON / gRPC-gateway conventions), while retaining the existing snake_case parameters as deprecated fallbacks for backward compatibility.
Changes:
- Introduces a shared query parsing module with canonical + deprecated query parameter constants and a
getQueryParamhelper. - Updates
/api/v3/traces/{trace_id}and/api/v3/operationshandlers to accept camelCase query params with snake_case fallbacks. - Expands/updates tests to cover deprecated aliases and canonical parameter names.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/query_parser.go | Adds canonical camelCase params, deprecated snake_case aliases, getQueryParam, and moved parseFindTracesQuery. |
| cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/http_gateway.go | Switches handlers to use canonical params with deprecated fallbacks; removes old in-file constants/parser. |
| cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/http_gateway_test.go | Adds/adjusts tests for canonical + deprecated param support and error messaging expectations. |
| cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/gateway_test.go | Updates operations endpoint test to use canonical spanKind. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Yuri Shkuro <github@ysh.us>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8625 +/- ##
==========================================
+ Coverage 96.59% 96.60% +0.01%
==========================================
Files 331 332 +1
Lines 17571 17575 +4
==========================================
+ Hits 16972 16978 +6
+ Misses 451 450 -1
+ Partials 148 147 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Backend PR jaegertracing/jaeger#8625 added support for camelCase parameter names, aligning the HTTP gateway with the OpenAPI spec. Switch from snake_case (query.service_name) to camelCase (query.serviceName) for all FindTraceSummaries query parameters. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Yuri Shkuro <github@ysh.us>
## Summary * Part of jaegertracing/jaeger#8606 — UI side: Milestone 2 (switch search results to `/api/v3/trace-summaries`) * Part of #3265 The search results page now loads trace summaries from the `/api/v3/trace-summaries` endpoint instead of fetching full traces from `/api/v1/`. This delivers the network-size reduction described in ADR-010 Milestone 2: response size is reduced by ≥ 80% for traces with many spans since only pre-computed summary fields are returned rather than full span data. - Query params now use camelCase (`query.serviceName`, `query.startTimeMin`, etc.) matching the OpenAPI spec and backend PR jaegertracing/jaeger#8625 - Response is validated at runtime with Zod schemas generated from the `jaeger-idl` OpenAPI spec (`openapi-zod-client`) - Only `traceId` is required; all other summary fields have sensible fallbacks so the UI degrades gracefully against partial/future backend implementations - The `traceID` (uppercase D) vs `traceId` wire-name inconsistency is handled transparently via schema normalization - Nanosecond timestamps are converted to microseconds using BigInt arithmetic to avoid float64 precision loss ## Schema generation approach Types and Zod validation schemas are auto-generated from `jaeger-idl` OpenAPI spec. The `jaeger-idl` proto now carries `field_behavior = REQUIRED` annotations on `TraceSummary.trace_id` and `ServiceSummary.name` (PR jaegertracing/jaeger-idl#204), so the generated schemas express correct optionality directly — no post-processing overrides needed. `schemas.ts` adds only thin format constraints (hex regex for trace ID, decimal-string check for nanosecond timestamps). ## Required vs optional fields | Field | Required | Fallback | |---|---|---| | `traceId` | ✅ | — | | `rootServiceName` | optional | `''` | | `rootOperationName` | optional | `''` | | `minStartTimeUnixNano` | optional | clamped to `maxEnd` or `0` | | `maxEndTimeUnixNano` | optional | clamped to `minStart` or `0` | | `spanCount` | optional | `0` | | `errorSpanCount` | optional | `0` | | `orphanSpanCount` | optional | `0` | | `services[].name` | ✅ | — | | `services[].spanCount` | optional | `0` | | `services[].errorSpanCount` | optional | `0` | ## Test plan - [x] Unit tests for `JaegerClient` covering all field combinations, timeout, error responses, and URL construction - [x] `npm run lint && npm test && npm run build` pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Yuri Shkuro <github@ysh.us> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…precated aliases (jaegertracing#8625) ## Summary Part 2 of jaegertracing#8619. - Moves all query param constants and `parseFindTracesQuery` into a new `query_parser.go` - Canonical param names are now camelCase (e.g. `query.serviceName`, `startTime`, `spanKind`) matching proto3 JSON encoding convention used by gRPC-gateway - All previous snake_case names (`query.service_name`, `start_time`, `span_kind`, etc.) are kept as deprecated fallbacks via a `getQueryParam` helper that prefers the canonical name - `query.num_traces` remains a deprecated alias for `query.searchDepth` (on top of the snake_case alias `query.search_depth`) No response body changes — the server already returns camelCase via `jsonpb.Marshaler`. ## Test plan - [ ] All existing tests pass - [ ] New `TestHTTPGatewayFindTracesDeprecatedParams` verifies all snake_case fallbacks for FindTraces - [ ] `TestHTTPGatewayGetTrace` has canonical + deprecated subtests for time window params - [ ] `TestHTTPGatewayGetOperationsErrors` tests both `spanKind` (canonical) and `span_kind` (deprecated) - [ ] Error messages include the actual param name used (canonical or deprecated), so clients get actionable feedback 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Yuri Shkuro <github@ysh.us> Signed-off-by: Victor Chidera Obiezue <obiezuechidera@gmail.com>
…racing#3964) ## Summary * Part of jaegertracing/jaeger#8606 — UI side: Milestone 2 (switch search results to `/api/v3/trace-summaries`) * Part of jaegertracing#3265 The search results page now loads trace summaries from the `/api/v3/trace-summaries` endpoint instead of fetching full traces from `/api/v1/`. This delivers the network-size reduction described in ADR-010 Milestone 2: response size is reduced by ≥ 80% for traces with many spans since only pre-computed summary fields are returned rather than full span data. - Query params now use camelCase (`query.serviceName`, `query.startTimeMin`, etc.) matching the OpenAPI spec and backend PR jaegertracing/jaeger#8625 - Response is validated at runtime with Zod schemas generated from the `jaeger-idl` OpenAPI spec (`openapi-zod-client`) - Only `traceId` is required; all other summary fields have sensible fallbacks so the UI degrades gracefully against partial/future backend implementations - The `traceID` (uppercase D) vs `traceId` wire-name inconsistency is handled transparently via schema normalization - Nanosecond timestamps are converted to microseconds using BigInt arithmetic to avoid float64 precision loss ## Schema generation approach Types and Zod validation schemas are auto-generated from `jaeger-idl` OpenAPI spec. The `jaeger-idl` proto now carries `field_behavior = REQUIRED` annotations on `TraceSummary.trace_id` and `ServiceSummary.name` (PR jaegertracing/jaeger-idl#204), so the generated schemas express correct optionality directly — no post-processing overrides needed. `schemas.ts` adds only thin format constraints (hex regex for trace ID, decimal-string check for nanosecond timestamps). ## Required vs optional fields | Field | Required | Fallback | |---|---|---| | `traceId` | ✅ | — | | `rootServiceName` | optional | `''` | | `rootOperationName` | optional | `''` | | `minStartTimeUnixNano` | optional | clamped to `maxEnd` or `0` | | `maxEndTimeUnixNano` | optional | clamped to `minStart` or `0` | | `spanCount` | optional | `0` | | `errorSpanCount` | optional | `0` | | `orphanSpanCount` | optional | `0` | | `services[].name` | ✅ | — | | `services[].spanCount` | optional | `0` | | `services[].errorSpanCount` | optional | `0` | ## Test plan - [x] Unit tests for `JaegerClient` covering all field combinations, timeout, error responses, and URL construction - [x] `npm run lint && npm test && npm run build` pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Yuri Shkuro <github@ysh.us> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Part 2 of #8619.
parseFindTracesQueryinto a newquery_parser.goquery.serviceName,startTime,spanKind) matching proto3 JSON encoding convention used by gRPC-gatewayquery.service_name,start_time,span_kind, etc.) are kept as deprecated fallbacks via agetQueryParamhelper that prefers the canonical namequery.num_tracesremains a deprecated alias forquery.searchDepth(on top of the snake_case aliasquery.search_depth)No response body changes — the server already returns camelCase via
jsonpb.Marshaler.Test plan
TestHTTPGatewayFindTracesDeprecatedParamsverifies all snake_case fallbacks for FindTracesTestHTTPGatewayGetTracehas canonical + deprecated subtests for time window paramsTestHTTPGatewayGetOperationsErrorstests bothspanKind(canonical) andspan_kind(deprecated)🤖 Generated with Claude Code