Skip to content

refactor(web): consistent error schema, response envelope, and introspection endpoints #541

@dekobon

Description

@dekobon

Decided (2026-06-05): uniform JSON error body for all errors; uniform {id, language, <result>} envelope on every endpoint; unit query accepts true/false/1/0 (case-insensitive); add additive /v1/version + /v1/languages. See the resolved-decisions comment.

Summary

The REST surface has inconsistent error-body schemas and response envelopes
across endpoints and content types. Worth standardizing before the /v1 surface
hardens for the long term.

Findings

  1. Error body differs by content type. JSON handlers emit structured
    {id, error} (big-code-analysis-web/src/web/server.rs:178,
    server.rs:334); octet-stream/plain handlers emit bare text/plain
    "error: <msg>" (server.rs:299, server.rs:373); the 415/405 fallbacks
    emit yet another plain-text shape (server.rs:556). The id correlation
    field exists only in JSON responses. Error-parsing clients must special-case
    per content type.

  2. Inconsistent success envelopes. /metrics returns
    {id, language, spaces} (metrics.rs:28), but /function returns
    {id, spans} (function.rs:19) and /comment returns {id, code}
    (comment.rs:18). Only /metrics echoes the detected language; clients of
    /function / /comment cannot learn which grammar was selected.

  3. Asymmetric truthiness. WebMetricsInfo.unit is bool in the JSON
    payload (metrics.rs:22) but a bespoke truthy-string set
    ({"1","true","yes","on"}) in the query variant (server.rs:350).

  4. No introspection. /ping returns an empty body (server.rs:427); there
    is no /v1/version or /v1/languages endpoint, unlike the Python surface
    (__version__, supported_languages(), language_extensions()). Adding
    endpoints is additive (can land pre-2.0).

Why 2.0-worthy

Items 1–3 freeze response shape; standardizing them is breaking. Item 4 is
additive. Bundling because they all concern the long-term /v1 contract (#517
versioned the routes; this hardens their payloads).

Proposed change

  • Standardize one machine-readable error schema (JSON problem-details style)
    across all error responses, or explicitly document the two-shape contract.
  • Consider a uniform {id, language, …} success envelope.
  • Unify unit truthiness or document the split.
  • Add /v1/version + /v1/languages for parity with the Python surface.

Part of the pre-2.0 review (#505).


Resolution

Implemented on fix/issue-541 (commit 57c05797); all four decisions landed exactly.

  1. Uniform JSON error body — single json_error helper; every error (JSON, octet-stream, 415/405/404) returns {error, id} + correct status. id always present (empty when absent). (breaking)
  2. Uniform success envelope/function + /comment gain id + language (fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540 slug via guess_languageLANG::name()), matching /metrics. (breaking)
  3. unit query flagtrue/false/1/0 case-insensitive, else HTTP 400 JSON; dropped yes/on. (breaking)
  4. IntrospectionGET /v1/version (server + library) and GET /v1/languages (slugs + extensions from the LANG table), plus unprefixed aliases. Added big_code_analysis::VERSION. (additive)

Docs (book commands/rest.md, STABILITY.md) updated; new + updated tests in server_tests.rs; full workspace fmt/clippy/test clean. Self-scan baseline refreshed for the resulting server.rs/lib.rs metric growth. Left open for the integration-branch merge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions