Skip to content

feat: force the app onto a given API version #85

Description

@MaxMichel2

Part of #72

Depends on #5. Explicitly deferred out of 0.2.0 scope by design — see the epic's "Version behaviour" decision.

Summary

An opt-in feature that lets a user force the app onto a specific API version by rewriting the outgoing request path (e.g. /api/v1/profile/{id}/api/v2/profile/{id}) before the request leaves the client — for both mocked and live requests.

Why this is separate from #5, and why it's deferred

#5 gives operations a display-only version tag: the engine always responds to whichever version the app actually calls, and a v2 mock can sit unused until the app (or a feature flag) actually starts calling /api/v2/.... That's the safe default: it never touches real network traffic, and it can't cause an app to receive a response shape its parser doesn't expect.

This issue is the opposite: forcing a version means rewriting the outgoing path regardless of what the app called, which:

  • mutates real network traffic when mocking is off, not just mock selection — a materially bigger blast radius than anything else in this migration
  • can cause an app's /api/v1 response parser to receive a /v2 payload shape, which might be exactly the point (testing forward-compatibility) or might just crash the app, depending on intent
  • needs its own design pass: does it rewrite only mocked requests, or live ones too? does it live at the Ktor plugin level (devview-networkmock-ktor) since that's the only place that sees outgoing requests before they're sent? what happens if the "target" version doesn't have an operation matching the current path?

Given that scope and risk, this was deliberately scoped out of the 0.2.0 breaking release rather than bolted onto an already-large migration.

What to design (not yet decided — this issue starts with a design pass, not straight to implementation)

  • Where the "force to version X" setting lives (per-spec? per-operation? global?) and how it's surfaced in the UI (devview-networkmock) built in ⬆️ Update compose-multiplatform #7.
  • Whether it applies to live requests, mocked requests, or both — recommend starting with mocked-only (serve the v2 mock for a v1 call) since that has zero real-network blast radius, then treating live-request rewriting as a further explicit opt-in on top, given the risk described above.
  • How the plugin (devview-networkmock-ktor/src/commonMain/kotlin/com/worldline/devview/networkmock/ktor/plugin/NetworkMockPlugin.kt) rewrites the outgoing HttpRequestBuilder's URL before the request is sent (for the live-request case) — this is new territory; today the plugin only ever intercepts and substitutes a full response (createMockHttpClientCall, NetworkMockPlugin.kt:322-346), it never mutates an outgoing request that proceeds to the real network.
  • What happens when the forced-to version doesn't have an operation at the equivalent path (e.g. v2 dropped an endpoint that existed in v1).

Acceptance criteria (to refine once design is settled)

  • A design doc or plan is written and reviewed before implementation starts, given the risk profile described above.
  • Whatever ships is opt-in and defaults to off — the observed-only behavior from Feature/documentation #5 remains the default.
  • Live-request rewriting (if built at all) is clearly separated from mocked-request version switching, both in code and in the UI, given the very different risk levels.

Files likely touched

TBD pending design — likely devview-networkmock-ktor's plugin, devview-networkmock-core's matching logic, and devview-networkmock's UI.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions