OpenAPI Spec Versioning — Rollback, Diff & Activate

Every spec import creates a new version. Previous versions are preserved in Cloudflare R2 and can be activated, inspected, or deleted at any time. Only one version is active per Mock API.

// How Versioning Works

Each time you import a spec, moqapi automatically:

  1. Hashes the spec content to detect duplicates
  2. Assigns an auto-incrementing version number
  3. Uploads the raw spec to R2 at specs/{mockApiId}/v{N}.{json|yaml}
  4. Deactivates the previous active version
  5. Parses all endpoints, parameters, and error responses into the database
  6. Activates the new version
version-lifecycle.txttext
Import v1 (petstore.yaml)    → Active ✓
Import v2 (petstore-v2.yaml) → v1 deactivated, v2 Active ✓
Rollback to v1               → v2 deactivated, v1 Active ✓
Delete v2                    → v2 removed from R2 + DB

// List All Versions

Fetch all spec versions for a Mock API, ordered by version number descending. Each version includes the endpoint count and active status.

terminalbash
curl https://moqapi.dev/api/mock-apis/<mockApiId>/specs
response.jsonjson
[
  {
    "id": "spec-uuid-2",
    "version_number": 2,
    "spec_name": "Petstore v2",
    "format": "yaml",
    "is_active": true,
    "endpoint_count": 19,
    "created_at": "2025-01-15T10:30:00Z"
  },
  {
    "id": "spec-uuid-1",
    "version_number": 1,
    "spec_name": "Petstore",
    "format": "yaml",
    "is_active": false,
    "endpoint_count": 12,
    "created_at": "2025-01-10T08:00:00Z"
  }
]

// Activate a Version (Rollback)

Switch the active spec version. All incoming requests will immediately be routed through the newly activated version's endpoints.

terminalbash
# Activate version 1 (rollback)
curl -X POST https://moqapi.dev/api/mock-apis/<mockApiId>/specs/<specId>/activate

# Response
{
  "message": "Spec version activated",
  "version_number": 1,
  "endpoints": 12
}

⚠ Activation is instant. Existing mock data is not affected—only endpoint routing changes.

// Inspect a Version

Get the full detail of a spec version, including all parsed endpoints. Optionally include the original spec content from R2.

terminalbash
# Get spec detail with endpoints
curl https://moqapi.dev/api/mock-apis/<mockApiId>/specs/<specId>

# Include original spec content
curl https://moqapi.dev/api/mock-apis/<mockApiId>/specs/<specId>?includeContent=true
response.jsonjson
{
  "spec": {
    "id": "spec-uuid",
    "version_number": 2,
    "spec_name": "Petstore v2",
    "format": "yaml",
    "is_active": true
  },
  "endpoints": [
    {
      "path": "/pet",
      "method": "GET",
      "operation_id": "listPets",
      "description": "List all pets",
      "parameters": [
        { "name": "limit", "in": "query", "type": "integer" }
      ],
      "error_responses": {}
    },
    {
      "path": "/pet/{petId}",
      "method": "GET",
      "operation_id": "getPetById",
      "is_parameterized": true,
      "path_pattern": "^\\/pet\\/([^/]+)$",
      "error_responses": {
        "404": { "description": "Pet not found" }
      }
    }
  ]
}

// Delete a Version

Remove a spec version from both the database and R2 storage. If the deleted version was active, the previous version is automatically activated.

terminalbash
curl -X DELETE "https://moqapi.dev/api/mock-apis/<mockApiId>/specs?specId=<specId>"

# Response
{
  "message": "Spec version deleted",
  "activated_previous": true,
  "new_active_version": 1
}

// R2 Storage Layout

Spec files are stored in Cloudflare R2 with a predictable key structure. This enables efficient retrieval and cleanup.

r2-layout.txttext
bucket/
├── specs/
│   ├── <mockApiId-1>/
│   │   ├── v1.yaml
│   │   ├── v2.yaml
│   │   └── v3.json
│   └── <mockApiId-2>/
│       └── v1.yaml

Storage Details

  • Content hash stored in DB to detect duplicate uploads
  • R2 gracefully degrades—if not configured, specs are still parsed into DB
  • Admin cleanup can purge inactive spec files via Settings → Cleanup

// API Reference

POST/api/mock-apis/:id/import
GET/api/mock-apis/:id/specs
GET/api/mock-apis/:id/specs/:specId
POST/api/mock-apis/:id/specs/:specId/activate
DELETE/api/mock-apis/:id/specs?specId=:id