Documentation Index
Fetch the complete documentation index at: https://mintlify.com/magooney-loon/pb-ext/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The APIVersionManager orchestrates versioned API documentation by maintaining isolated registries, parsers, and configurations for each API version. It enables side-by-side deployment of multiple API versions with automatic OpenAPI spec generation and Swagger UI support.
Type Definition
type APIVersionManager struct {
mu sync.RWMutex
versions []string // ordered list of versions
defaultVersion string // default version to use
registries map[string]*APIRegistry // separate registry per version
configs map[string]*APIDocsConfig // version-specific configs
routeRegistrars map[string]func(*VersionedAPIRouter) // per-version route registration callbacks
createdAt time.Time // when manager was created
lastModified time.Time // last time versions were modified
}
Each API version gets its own isolated ASTParser, SchemaGenerator, and APIRegistry. This ensures complete separation between versions with independent component schemas and route registrations.
Constructor Functions
NewAPIVersionManager
func NewAPIVersionManager() *APIVersionManager
Creates a new version manager with empty state.
Returns:
*APIVersionManager - New manager instance
Example:
vm := api.NewAPIVersionManager()
NewAPIVersionManagerWithDefault
func NewAPIVersionManagerWithDefault(defaultVersion string) *APIVersionManager
Creates a version manager with a pre-set default version.
Version identifier to use as default (e.g., “v1”, “v2”)
Example:
vm := api.NewAPIVersionManagerWithDefault("v1")
Version Management
RegisterVersion
func (vm *APIVersionManager) RegisterVersion(version string, config *APIDocsConfig) error
Registers a new API version with its own registry and configuration.
Version identifier (e.g., “v1”, “v2”, “beta”)
Version-specific configuration (can be nil for defaults)
Returns:
error - Error if version already exists or validation fails
Behavior:
- Validates version string format
- Creates version-specific AST parser and schema generator
- Creates isolated API registry for the version
- Sets version-specific server URL in OpenAPI spec
- Automatically becomes default version if first registered
Example:
config := &api.APIDocsConfig{
Title: "My API v1",
Version: "v1",
BaseURL: "https://api.example.com",
Status: "stable",
}
err := vm.RegisterVersion("v1", config)
RemoveVersion
func (vm *APIVersionManager) RemoveVersion(version string) error
Removes a version and its registry. Cannot remove the default version.
Version identifier to remove
GetVersionConfig
func (vm *APIVersionManager) GetVersionConfig(version string) (*APIDocsConfig, error)
Retrieves the configuration for a specific version.
Location: core/server/api/version_manager.go:198
GetVersionRegistry
func (vm *APIVersionManager) GetVersionRegistry(version string) (*APIRegistry, error)
Retrieves the API registry for a specific version.
Location: core/server/api/version_manager.go:209
Route Registration
SetVersionRouteRegistrar
func (vm *APIVersionManager) SetVersionRouteRegistrar(
version string,
registrar func(*VersionedAPIRouter),
) error
Sets the route registration callback for a version.
registrar
func(*VersionedAPIRouter)
required
Function that registers routes for this version
Example:
err := vm.SetVersionRouteRegistrar("v1", func(router *api.VersionedAPIRouter) {
router.GET("/users", listUsersHandler)
router.POST("/users", createUserHandler)
})
RegisterAllVersionRoutes
func (vm *APIVersionManager) RegisterAllVersionRoutes(e *core.ServeEvent) error
Registers all version routes to a ServeEvent router and docs registries.
Location: core/server/api/version_manager.go:300
RegisterAllVersionRoutesForDocs
func (vm *APIVersionManager) RegisterAllVersionRoutesForDocs() error
Registers all version routes only to docs registries (for build-time spec generation).
Location: core/server/api/version_manager.go:315
GetDefaultVersion
func (vm *APIVersionManager) GetDefaultVersion() string
Returns the default version identifier.
SetDefaultVersion
func (vm *APIVersionManager) SetDefaultVersion(version string) error
Sets the default API version. Version must exist.
GetAllVersions
func (vm *APIVersionManager) GetAllVersions() []string
Returns all registered versions (sorted). Returns a copy to prevent external modifications.
GetVersionInfo
func (vm *APIVersionManager) GetVersionInfo(version string) (*VersionInfo, error)
Returns detailed information about a specific version.
Returns:
type VersionInfo struct {
Version string `json:"version"`
Status string `json:"status"` // "stable", "development", "deprecated"
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Config *APIDocsConfig `json:"config"`
Stats map[string]int `json:"stats"`
Endpoints int `json:"endpoints"`
}
Location: core/server/api/version_manager.go:650
HTTP Handlers
RegisterWithServer
func (vm *APIVersionManager) RegisterWithServer(app core.App)
Registers version management endpoints with the PocketBase app:
GET /api/docs/versions - List all versions (requires auth)
GET /api/docs/debug/ast - AST pipeline introspection (requires auth)
GET /api/docs/{version} - Version-specific OpenAPI spec (requires auth)
GET /api/docs/{version}/spec - Public OpenAPI spec (if PublicSwagger enabled)
GET /api/docs/{version}/swagger - Swagger UI (if PublicSwagger enabled)
GET /api/{version}/schema/config - Schema configuration (requires auth)
Location: core/server/api/version_manager.go:706
VersionsHandler
func (vm *APIVersionManager) VersionsHandler(c *core.RequestEvent) error
HTTP handler that returns list of all available API versions.
Response:
{
"versions": [...],
"default_version": "v1",
"total_versions": 2,
"generated_at": "2024-03-04T12:00:00Z"
}
Location: core/server/api/version_manager.go:756
GetVersionOpenAPI
func (vm *APIVersionManager) GetVersionOpenAPI(
c *core.RequestEvent,
version string,
) error
Returns the complete OpenAPI schema for a specific version.
Priority:
- Direct spec loading from disk (if available)
- Fallback to runtime registry generation
Location: core/server/api/version_manager.go:827
ServeSwaggerUI
func (vm *APIVersionManager) ServeSwaggerUI(
c *core.RequestEvent,
version string,
) error
Serves the Swagger UI HTML page for the given API version with dark mode support.
Location: core/server/api/version_manager.go:898
Uses SwaggerDark theme by Amoenus (MIT License) for automatic dark mode support based on user’s system preferences.
Complete Example
package main
import (
"github.com/magooney-loon/pb-ext/core/server/api"
"github.com/pocketbase/pocketbase/core"
)
func setupVersionedAPI(app core.App) (*api.APIVersionManager, error) {
// Create version manager
vm := api.NewAPIVersionManagerWithDefault("v1")
// Register v1
v1Config := &api.APIDocsConfig{
Title: "My API v1",
Version: "v1",
BaseURL: "https://api.example.com",
Status: "stable",
PublicSwagger: true,
}
if err := vm.RegisterVersion("v1", v1Config); err != nil {
return nil, err
}
// Register v2 (beta)
v2Config := &api.APIDocsConfig{
Title: "My API v2 (Beta)",
Version: "v2",
BaseURL: "https://api.example.com",
Status: "development",
PublicSwagger: false,
}
if err := vm.RegisterVersion("v2", v2Config); err != nil {
return nil, err
}
// Register routes for each version
if err := vm.SetVersionRouteRegistrar("v1", registerV1Routes); err != nil {
return nil, err
}
if err := vm.SetVersionRouteRegistrar("v2", registerV2Routes); err != nil {
return nil, err
}
// Register HTTP endpoints
vm.RegisterWithServer(app)
return vm, nil
}
func registerV1Routes(router *api.VersionedAPIRouter) {
api := router.SetPrefix("/api/v1")
api.GET("/users", listUsersHandler)
api.POST("/users", createUserHandler)
api.GET("/users/{id}", getUserHandler)
}
func registerV2Routes(router *api.VersionedAPIRouter) {
api := router.SetPrefix("/api/v2")
// v2 has additional endpoints
api.GET("/users", listUsersV2Handler)
api.POST("/users", createUserV2Handler)
api.GET("/users/{id}", getUserV2Handler)
api.PATCH("/users/{id}", patchUserHandler) // New in v2
}
Best Practices
- Version Naming: Use semantic versions (“v1”, “v2”) or descriptive names (“stable”, “beta”)
- Default Version: Always set a stable version as default
- Public Access: Only enable
PublicSwagger for stable, production-ready versions
- Route Isolation: Use
SetPrefix() to namespace each version’s routes
- Deprecation: Mark old versions with
Status: "deprecated" before removal
- Testing: Use
RegisterAllVersionRoutesForDocs() for build-time spec generation