Skip to content

ADR-0005: POST Body Over Path Variables for Resource Operations

Status: ACCEPTED Date: 2026-03-23 Supersedes: N/A Superseded by: N/A

Context

The original API design used REST-style path variables (/workspaces/{id}/roles/{roleId}) to identify resources. This created several problems: ambiguous semantics (is {id} the user's workspace or the target workspace?), deeply nested URLs, and mixing of permission context with resource identifiers in the same path.

Source: docs/archive/specs/2026-03-23-workspace-context-header-design.md, DevPortal design spec (@PathVariable handling), governance rule in .proteus/ memory

Decision

All business parameters go in the request body (JSON), not in path variables. Path segments carry endpoint identity only (e.g., /workspaces/admin/query). GET endpoints that need resource identifiers are converted to POST to carry a body. Existing @PathVariable usage is flagged by the API toolkit parser with x-deprecated-path-variable: true in OpenAPI output. No new path variables are permitted.

Consequences

  • Unambiguous API contracts: the body schema is the complete interface definition.
  • Eliminates deeply nested URL patterns and the maintenance burden of URL routing rules.
  • All admin/cross-entity endpoints become POST, which may feel non-RESTful but is consistent and unambiguous.
  • Frontend and SDK consumers must adapt from URL construction to body construction for affected endpoints.
  • Parser and linter enforce the rule; violations are caught at CI time.

Alternatives Considered

  • Conventional REST paths: Rejected because nested resource hierarchies (/workspaces/{id}/institutions/{instId}/portals/{portalId}) became unwieldy and semantically ambiguous.
  • Query parameters for resource IDs: Rejected because query parameters are logged by default in many infrastructure layers, creating potential data exposure for sensitive identifiers.

Internal Handbook