# API Versioning Strategy **Status:** Active — Current version: **v1** All BanGUI API endpoints are versioned using URI path versioning (e.g., `/api/v1/`). This document explains when and how to version endpoints, how deprecation works, and what guarantees consumers can rely on. --- ## 1. Version Lifecycle | Stage | Meaning | |-------|---------| | **Current** | Active, receiving new features and bug fixes. | | **Deprecated** | Still functional but marked for removal. Clients receive `Deprecation: true` and `Sunset: ` response headers. | | **Removed** | Endpoint no longer exists. Clients must migrate to a newer version. | --- ## 2. URL Structure ``` /api/v{major}// ``` - **v1** — current version (2026-05-02) - **v2** — reserved for future breaking changes - **PATCH** versions (v1.1, v1.2) are **not** used; only **major** version bumps indicate breaking changes - The OpenAPI schema is always available at `/api/openapi.json` regardless of version --- ## 3. What Triggers a Version Bump A new major version is required when a **breaking change** must be introduced, including: - Removing or renaming a field in a response model - Changing the type of a request or response field - Removing an endpoint entirely - Changing authentication/authorization semantics - Modifying the semantics of an existing operation **Non-breaking changes** (backward-compatible): - Adding new optional request fields - Adding new response fields - Adding new endpoints - Fixing bugs that caused incorrect behavior These do **not** require a version bump. --- ## 4. Deprecation Policy When an endpoint is deprecated: 1. The endpoint **remains functional** for a minimum of **6 months** from the `Sunset` date 2. Response headers are added: ``` Deprecation: true Sunset: Link: ; rel="successor-version" ``` 3. The OpenAPI schema marks the endpoint with `deprecated: true` 4. Documentation is updated to show the endpoint as deprecated --- ## 5. Backend Development: Adding Versioned Endpoints ### New endpoints All new endpoints are added to the **current** version (`/api/v1/`). Prefix your router: ```python router = APIRouter(prefix="/api/v1/my-resource", tags=["My Resource"]) ``` ### Breaking changes requiring v2 1. Create a new router file (e.g., `routers/my_resource_v2.py`) with the v2 prefix: ```python router = APIRouter(prefix="/api/v2/my-resource", tags=["My Resource"]) ``` 2. Copy or adapt the v1 handler logic as needed 3. Register the new router in `app/main.py`: ```python app.include_router(my_resource_v2.router) ``` 4. Add deprecation headers to the **old** v1 router by marking it deprecated in the OpenAPI spec 5. Update this document to reflect the new version lifecycle ### Keeping routers DRY If v1 and v2 share logic, extract business logic into a **service layer function** and call it from both router handlers. Routers should only contain HTTP concerns (parameters, responses, status codes). --- ## 6. Frontend Development The frontend always uses the current version's base URL: ```typescript const BASE_URL: string = import.meta.env.VITE_API_URL ?? "/api/v1"; ``` All endpoint paths in `frontend/src/api/endpoints.ts` are defined as relative paths (e.g., `/bans`, `/jails`) and are appended to `BASE_URL` at runtime. --- ## 7. OpenAPI / Documentation - Swagger UI: `/api/docs` - ReDoc: `/api/redoc` - OpenAPI schema: `/api/openapi.json` - Docs are **not** versioned; they always reflect the **current** (latest) API version --- ## 8. Version History | Version | Status | Released | Sunset Date | Notes | |---------|--------|---------|-------------|-------| | v1 | **Current** | 2026-05-02 | — | Initial versioning; all endpoints moved from `/api/` to `/api/v1/` |