Spec Generation
pb-ext supports both runtime and build-time OpenAPI spec generation. For production deployments, specs should be generated during the build process and read from disk at runtime for optimal performance.Dev vs Production
Development Mode
- No disk specs — specs are generated at runtime via AST parsing
- Specs regenerate on server restart (picks up code changes)
- Slightly slower startup due to AST analysis
- No build toolchain required
Production Mode
- Specs generated at build time and copied to
dist/specs/ - Binary reads specs from disk at runtime
- Fast startup (no AST parsing)
- Specs are validated during build
- Generated specs are version-controlled
dist/specs/ and bundles them with the final binary.
Build Pipeline Integration
Thepb-cli toolchain automatically runs OpenAPI generation for production builds:
What Happens During Build
- Frontend build (if applicable)
- Spec generation:
--generate-specs-dir=dist/specs - Spec validation: Ensures all required fields present
- Go build with specs copied to final artifact
Programmatic Generation
Generate specs from your own code:Using SpecGenerator
From main.go
The typical pattern incmd/server/main.go:
Validation
ValidateSpecs
Validate generated specs to ensure they’re valid OpenAPI 3.0:- File exists and is readable JSON
- Required fields present:
openapi,info,info.title,info.version,paths - Filename matches version (e.g.,
v1.jsonfor versionv1)
ValidateSpecFile
Validate a single spec file:From main.go
Generated Spec Location
Specs are written to the output directory with version-based filenames:- All paths and operations
- Component schemas (structs)
- Parameters, request bodies, responses
- Security requirements
- API metadata (title, description, contact, license)
Runtime Spec Loading
At runtime, pb-ext follows this source selection policy:- If
PB_EXT_OPENAPI_SPECS_DIRenv var is set, read from that directory - Otherwise, read from
dist/specs/relative to the binary - If no specs found on disk, fall back to runtime AST generation (dev mode)
Environment Variables
PB_EXT_OPENAPI_SPECS_DIR: Override spec directory
PB_EXT_DISABLE_OPENAPI_SPECS: Force runtime generation (ignore disk)
Caching and Deep Copy
Caching: Parsed specs are cached per version in memory after first load. Deep Copy: Returned specs are deep-copied to avoid mutation leaks across requests. This ensures concurrent Swagger UI requests don’t interfere with each other.Integration with APIVersionManager
TheAPIVersionManager coordinates spec loading:
- Check if disk spec exists via
HasEmbeddedSpec(version) - If yes, load via
GetEmbeddedSpec(version)(cached) - If no, fall back to runtime
GenerateComponentSchemas()via AST
Testing Spec Generation
Create a test that generates and validates specs:CI/CD Integration
GitHub Actions
Makefile
Spec Format
Generated specs follow OpenAPI 3.0.3 format:Common Issues
Missing Specs in Production
Problem: Server falls back to runtime AST parsing in production. Solution: Ensure specs are copied to the correct location:Validation Failures
Problem:ValidateSpecs fails with missing required field.
Solution: Check your APIDocsConfig has all required fields:
Stale Specs
Problem: OpenAPI docs don’t reflect recent code changes. Solution: Regenerate specs:Best Practices
Version-Control Specs
Commit generated specs to Git so reviewers can see API changes in PRs.
Validate in CI
Run
--validate-specs-dir in CI to catch invalid specs before deployment.Use Build Flag
Always use
pb-cli --production for prod builds to ensure specs are bundled.Cache Busting
If specs don’t update, clear cache:
rm -rf dist/specs && pb-cli --build-onlyFurther Reading
- AST Parsing - How specs are generated from code
- Reserved Routes - API docs routes
- Middleware - Request/response middleware patterns