-
Notifications
You must be signed in to change notification settings - Fork 168
Open
Labels
enhancementNew feature or requestNew feature or requestpythonPython / backend development (FastAPI)Python / backend development (FastAPI)triageIssues / Features awaiting triageIssues / Features awaiting triage
Milestone
Description
π§ Epic - API Path Versioning
Field | Value |
---|---|
Title | Path-Based API Versioning with Rapid Legacy Deprecation |
Target Release | 0.6.0 (implementation) β 0.7.0 (legacy removal) |
Goal | Introduce clean API versioning with minimal legacy support window for faster development velocity |
Breaking Change | Yes β clients have one minor release to migrate |
Migration Period | One release cycle (0.6.0 β 0.7.0) with deprecation warnings |
Depends on | JWT Token Catalog (#87), RBAC (#283) for experimental endpoint access |
Related | Future GraphQL faΓ§ade (will mount under /experimental/graphql ) |
π§ Type of Feature
- Developer experience
- Breaking change (aggressive timeline)
- Documentation
- API standardization
πββοΈ User Stories
# | Persona | Need | Acceptance Criteria |
---|---|---|---|
1 | Platform developer | Clean API versioning for rapid feature development | All endpoints under /v1/* , /experimental/* with clear separation |
2 | Integrator | Clear migration path with minimal disruption | Deprecation warnings in 0.6.0, migration guide, working examples |
3 | CI engineer | Early detection of legacy usage | Contract tests fail on bare paths in 0.7.0, pass on versioned paths |
π Enhanced Technical Design
flowchart TD
subgraph FastAPI_App
V1["/v1 routers"] --> C1["controllers v1"]
V2["/v2 routers"] --> C2["controllers v2"]
EXP["/experimental routers"] --> CX["experimental controllers"]
end
# Fast-track versioning configuration
class VersioningConfig:
# 0.6.0 settings
enable_legacy_support: bool = True # Still serve legacy in 0.6.0
enable_deprecation_headers: bool = True # Loud warnings
legacy_removal_version: str = "0.7.0" # Hard deadline
# 0.7.0 settings
legacy_support_removed: bool = True # No more legacy paths
# Experimental access
experimental_access_roles: List[str] = ["platform_admin", "developer"]
Router Architecture:
app/
βββ routers/
β βββ v1/ # All current API (moved from root)
β β βββ tools.py # /v1/tools
β β βββ servers.py # /v1/servers
β β βββ resources.py # /v1/resources
β β βββ prompts.py # /v1/prompts
β β βββ metrics.py # /v1/metrics
β β βββ auth.py # /v1/auth
β βββ experimental/ # Rapid prototyping
β β βββ graphql.py # /experimental/graphql
β β βββ batch.py # /experimental/batch-operations
β βββ legacy.py # 0.6.0 only - removed in 0.7.0
βββ middleware/
β βββ versioning.py # Route handling & deprecation
β βββ experimental_access.py # RBAC for experimental
βββ schemas/
βββ v1/ # Stable schemas
βββ experimental/ # Unstable schemas
βββ legacy/ # Removed in 0.7.0
π Aggressive Roll-out Plan
Release | Timeline | Deliverables | Client Impact | Actions Required |
---|---|---|---|---|
0.6.0 | Immediate | β’ Move all routes to /v1/* β’ Add /experimental/* β’ Legacy support with loud warnings |
Deprecation warnings Legacy paths still work |
Clients must plan migration |
0.7.0 | Next release | β’ Remove all legacy paths β’ 404 on unversioned routes β’ Clean /v1/* only |
π₯ BREAKING Unversioned paths return 404 |
Migration mandatory |
π§ Detailed Task Breakdown
Phase 1: Implementation (0.6.0) - ASAP
-
Router Migration (Priority: Critical)
# main.py - New structure def create_app() -> FastAPI: app = FastAPI(title="MCP Gateway", version="0.6.0") # V1 API (stable) v1_app = FastAPI(title="MCP Gateway API v1", version="1.0.0") setup_v1_routes(v1_app) app.mount("/v1", v1_app) # Experimental API (RBAC protected) exp_app = FastAPI(title="MCP Gateway Experimental", version="0.1.0") setup_experimental_routes(exp_app) app.mount("/experimental", exp_app) # Legacy compatibility (0.6.0 ONLY) setup_legacy_deprecation_routes(app) return app
-
Aggressive Deprecation Middleware
class LegacyDeprecationMiddleware: async def __call__(self, request: Request, call_next): if is_legacy_path(request.url.path): # LOUD deprecation warnings logger.warning(f"DEPRECATED: {request.url.path} -> /v1{request.url.path}") response = await call_next(request) response.headers.update({ "X-API-Deprecated": "true", "X-API-Removal-Version": "0.7.0", "X-API-Migration-Guide": "/docs/migration-urgent", "Warning": "299 - \"This API version will be removed in 0.7.0. Migrate immediately.\"" }) return response
-
Experimental Access Control
@router.middleware("http") async def experimental_rbac(request: Request, call_next): if request.url.path.startswith("/experimental"): user = await require_auth(request) if not user_has_experimental_access(user): raise HTTPException( status_code=403, detail="Experimental API requires developer or platform_admin role" ) return await call_next(request)
Phase 2: Legacy Removal (0.7.0) - Next Release
-
Complete Legacy Removal
# main.py - 0.7.0 version (clean) def create_app() -> FastAPI: app = FastAPI(title="MCP Gateway", version="0.7.0") # Only versioned routes remain v1_app = FastAPI(title="MCP Gateway API v1", version="1.0.0") setup_v1_routes(v1_app) app.mount("/v1", v1_app) exp_app = FastAPI(title="MCP Gateway Experimental", version="0.2.0") setup_experimental_routes(exp_app) app.mount("/experimental", exp_app) # NO legacy routes - clean 404s return app
-
404 Handler for Legacy Paths
@app.exception_handler(404) async def legacy_path_404_handler(request: Request, exc: HTTPException): if could_be_legacy_path(request.url.path): return JSONResponse( status_code=404, content={ "error": "API endpoint not found", "message": f"Did you mean /v1{request.url.path}?", "migration_guide": "/docs/migration-urgent", "removed_in": "0.7.0" } ) return JSONResponse(status_code=404, content={"error": "Not found"})
π οΈ Migration Tooling & Documentation
Urgent Migration Script
#!/bin/bash
# migrate-to-versioned.sh - Fast migration helper
echo "π¨ URGENT: Migrating MCP Gateway API calls to versioned endpoints"
# Update configuration files
find . -name "*.json" -exec sed -i 's|http://localhost:4444/|http://localhost:4444/v1/|g' {} \;
find . -name "*.yaml" -exec sed -i 's|/tools|/v1/tools|g' {} \;
find . -name "*.py" -exec sed -i 's|"\/tools"|"/v1/tools"|g' {} \;
echo "β
Basic migration complete. Please review changes and test thoroughly."
echo "π See /docs/migration-urgent for detailed instructions"
Breaking Change Documentation
# π¨ URGENT: API Versioning Migration (0.6.0 β 0.7.0)
## β° Timeline
- **0.6.0 (NOW)**: Legacy paths deprecated with warnings
- **0.7.0 (NEXT RELEASE)**: Legacy paths removed completely
## π Required Changes
### Before (0.5.x and earlier):
```bash
curl http://localhost:4444/tools
curl http://localhost:4444/servers
curl http://localhost:4444/metrics
After (0.6.0+):
curl http://localhost:4444/v1/tools
curl http://localhost:4444/v1/servers
curl http://localhost:4444/v1/metrics
Claude Desktop Configuration:
{
"mcpServers": {
"gateway": {
"command": "python3",
"args": ["-m", "mcpgateway.wrapper"],
"env": {
"MCP_SERVER_CATALOG_URLS": "http://localhost:4444/v1/servers/123"
}
}
}
}
π§ SDK Updates
# Update to versioned SDK
pip install mcp-contextforge-gateway>=0.6.0
# New import paths
from mcpgateway.client.v1 import GatewayClient
---
### π **Testing Strategy**
```python
# Comprehensive version testing
class TestAPIVersioning:
def test_v1_endpoints_work(self):
"""All v1 endpoints return 200"""
for endpoint in ["/v1/tools", "/v1/servers", "/v1/metrics"]:
response = client.get(endpoint, headers=auth_headers)
assert response.status_code == 200
def test_legacy_deprecated_in_06(self):
"""Legacy paths work but show deprecation (0.6.0)"""
response = client.get("/tools", headers=auth_headers)
assert response.status_code == 200 # Still works
assert "X-API-Deprecated" in response.headers
assert "0.7.0" in response.headers["X-API-Removal-Version"]
def test_legacy_removed_in_07(self):
"""Legacy paths return 404 (0.7.0)"""
response = client.get("/tools", headers=auth_headers)
assert response.status_code == 404
assert "Did you mean /v1/tools?" in response.json()["message"]
def test_experimental_access_control(self):
"""Experimental endpoints require proper roles"""
# Regular user
response = client.get("/experimental/graphql", headers=user_headers)
assert response.status_code == 403
# Platform admin
response = client.get("/experimental/graphql", headers=admin_headers)
assert response.status_code in [200, 501] # Exists or not implemented
π Alternative Approaches (Rejected)
Approach | Why Rejected |
---|---|
Longer deprecation period | Slows development velocity, technical debt |
Header-based versioning | Not RESTful, breaks curl/browser usage |
Gradual endpoint migration | Inconsistent API, confusing for developers |
Redirect legacy β v1 | Hides the breaking change, delays migration |
π― Success Criteria
- 0.6.0: All endpoints available under
/v1/*
, legacy paths show deprecation warnings - 0.6.0: Experimental endpoints available under
/experimental/*
with RBAC - 0.6.0: Migration guide published, client examples updated
- 0.6.0: Deprecation headers present on all legacy requests
- 0.7.0: Legacy paths return 404 with helpful error messages
- 0.7.0: All documentation and examples use versioned paths
- 0.7.0: CI/CD passes with only versioned endpoint tests
π Monitoring & Metrics
# Track migration progress
VERSIONING_METRICS = {
"legacy_requests_total": "Counter of deprecated endpoint usage (should go to 0)",
"v1_requests_total": "Counter of v1 endpoint usage (should increase)",
"experimental_requests_total": "Counter of experimental endpoint usage",
"404_legacy_attempts": "Failed attempts to use removed legacy paths"
}
π§© Additional Notes
- π¨ Aggressive Timeline: One release cycle for migration is fast but drives quick adoption
- π’ Communication: Clear, loud deprecation warnings to ensure visibility
- π§ Tooling: Migration scripts and documentation to ease transition
- π― Focus: Clean API design trumps backward compatibility for faster iteration
- π Future: This pattern enables rapid v2, v3 development when needed
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestpythonPython / backend development (FastAPI)Python / backend development (FastAPI)triageIssues / Features awaiting triageIssues / Features awaiting triage