Versioning
Opt-in API versioning - URL-path (/api/v1/...) and accept-header (Accept; version=v2) schemes, allowed/default versions, and reading the resolved version on the request context.
API versioning lets one deployment serve several wire contracts at once - v1 for old clients, v2 for new ones - without forking the app. umbral-rest offers two versioning schemes.
Versioning is opt-in and off by default. A RestPlugin with no .versioning(...) call serves the unversioned API exactly as before: routes mount at /api/<table>/, no version is required, and RequestContext::version is always None.
The two schemes
Configuration
VersioningConfig::new(scheme) plus chainable builders:
.default_version("v1")- the version assumed when a request supplies none (header schemes)..allowed_version("v1")/.allowed_versions(["v1", "v2"])- the closed set of versions the API serves. A version outside this set is rejected (404 for URL-path, 406 for accept-header).
VersioningConfig::new(VersioningScheme::url_path()) .allowed_versions(["v1", "v2"]) .default_version("v1")Reading the version in a handler
A custom @action (or, later, a version-aware transform) reads the resolved version off the context:
ResourceConfig::new("post").action( "whoami", Method::GET, ActionScope::Collection, |ctx| async move { Ok(serde_json::json!({ "version": ctx.version })) },)Under URL-path versioning, GET /api/v2/post/whoami/ returns {"version":"v2"}.
Safe-by-default exposure (blocked tables, the password_hash strip), permissions, throttling, and pagination all stay intact under versioned paths.
See also
- Exposure - which tables are served, and the base path (
RestPlugin::at). - Permissions and Throttling - both apply under versioned paths.
- Design rationale: gaps2 #82 (REST remainder).