I've transformed your OpenAPI generation system from manual registration to automatic convention-based discovery. Your API endpoints are now automatically discovered and documented based on your SvelteKit file structure.
TypeScript type definitions for route metadata:
RouteOpenAPIMetadata- Main metadata export interfaceRouteMethodConfig- Configuration for each HTTP methodResponseDefinition- Response specifications
The route discovery engine:
- Recursively scans
src/routesfor+server.tsfiles - Converts SvelteKit paths (
[id]) to OpenAPI paths ({id}) - Dynamically imports routes and extracts metadata
- Returns discovered routes with their API paths
Comprehensive documentation for the generation system:
- How it works
- Usage examples
- Adding new endpoints
- Troubleshooting guide
Before/after comparison and migration instructions:
- Explains the problems solved
- Shows the benefits
- Provides examples for common scenarios
- FAQ section
Complete overview of the new system:
- Implementation details
- Key features
- Best practices
- Comparison with old approach
This file - quick reference for what changed.
Before: 170+ lines with manual registry.registerPath() calls for each endpoint
After: ~140 lines that automatically discover and register routes
- Uses
scanRoutes()to find all route files - Iterates over discovered routes and operations
- Automatically builds request/response objects
- Better error handling and logging
Added: _openapi export with metadata for GET and POST operations
- Metadata lives with implementation
- Uses Zod schemas directly
- Type-safe with
RouteOpenAPIMetadata
Added: _openapi export with metadata for GET, PUT, and DELETE operations
- Same pattern as above
- Multiple operations in one export
Updated sections:
- Project Structure - Added new script files
- Automatic OpenAPI Generation section - Explains convention-based system
- Adding New API Endpoints - Complete workflow with automatic discovery
- Benefits - Added convention-based benefits
- Create route file
- Open
scripts/generate-openapi.ts - Manually add
registry.registerPath()call - Type out the path string (prone to typos)
- Define request/response schemas
- Run generator
Problems:
- Duplication of route structure
- Easy to forget to update
- Maintenance burden
- Error-prone
-
Create route file with
_openapiexport:export const _openapi: RouteOpenAPIMetadata = { operations: [ { method: 'GET', summary: 'List users', tags: ['Users'], responses: [ { status: 200, description: 'List of users', schema: z.array(UserSchema) } ] } ] };
-
Run
npm run generate:openapi
Benefits:
- ✅ Single source of truth
- ✅ Automatic discovery
- ✅ Co-located documentation
- ✅ Type-safe
- ✅ Less code
- ✅ Fewer errors
When you run npm run generate:openapi:
🔍 Scanning SvelteKit routes...
⚠ Skipping /api/openapi.json: No '_openapi' export found
✓ Discovered route: /api/users (2 operations)
✓ Discovered route: /api/users/{id} (3 operations)
📝 Registering 2 routes...
✓ GET /api/users
✓ POST /api/users
✓ GET /api/users/{id}
✓ PUT /api/users/{id}
✓ DELETE /api/users/{id}
🎨 Generating OpenAPI document...
✅ OpenAPI spec generated at: /path/to/static/openapi.json
📊 Total operations: 5
Clear, informative output showing what was discovered!
The system automatically converts SvelteKit paths to OpenAPI format:
| SvelteKit Path | Becomes | OpenAPI Path |
|---|---|---|
src/routes/api/users/+server.ts |
→ | /api/users |
src/routes/api/users/[id]/+server.ts |
→ | /api/users/{id} |
src/routes/api/posts/[postId]/comments/[cid]/+server.ts |
→ | /api/posts/{postId}/comments/{cid} |
-
Create the route file:
src/routes/api/products/+server.ts
-
Define schema in shared package:
shared/src/schemas/product.schema.ts
-
Add
_openapiexport to route:import type { RouteOpenAPIMetadata } from '../../../scripts/types.js'; import { ProductSchema } from '@zod-schema-example/shared'; export const _openapi: RouteOpenAPIMetadata = { operations: [ { method: 'GET', summary: 'List products', tags: ['Products'], responses: [ { status: 200, description: 'Products', schema: z.array(ProductSchema) } ] } ] }; export const GET: RequestHandler = async () => { /* ... */ };
-
Build and regenerate:
npm run build:shared npm run generate:openapi
Done! The new route is automatically discovered and documented.
Routes are found automatically by scanning the file system. No manual registration needed.
All metadata is fully typed with TypeScript. Your IDE provides autocomplete and validation.
OpenAPI metadata lives right next to your route handlers, making it easy to keep them in sync.
Use your Zod schemas directly in the metadata. The system converts them to OpenAPI schemas automatically.
Follows SvelteKit's file-based routing conventions. Your route structure IS your API structure.
- Clear console output
- Informative warnings
- Better error messages
- Less boilerplate
The system has been tested and verified:
- ✅ Scans routes correctly
- ✅ Converts paths properly (
[id]→{id}) - ✅ Imports metadata successfully
- ✅ Generates valid OpenAPI spec
- ✅ All 5 operations registered correctly
- ✅ No linter errors
Comprehensive documentation has been created:
| File | Purpose |
|---|---|
scripts/README.md |
Technical documentation for the generation system |
MIGRATION_GUIDE.md |
Before/after comparison and migration guide |
CONVENTION_BASED_OPENAPI.md |
Complete overview and best practices |
README.md |
Updated main documentation |
CHANGES_SUMMARY.md |
This file - quick reference |
None! The system is fully backward compatible:
- Existing routes continue to work
- Route handlers unchanged
- Only added
_openapiexports - Can still manually register paths if needed (not recommended)
- ✅ System is ready to use
- ✅ Test by running
npm run generate:openapi - ✅ View generated spec in Swagger UI at
http://localhost:5173/api-docs - When adding new endpoints, just:
- Create route file with
_openapiexport - Run
npm run generate:openapi - Done!
- Create route file with
Check out:
scripts/README.md- Detailed technical guideMIGRATION_GUIDE.md- Examples and FAQCONVENTION_BASED_OPENAPI.md- Complete overview- Existing route files - Working examples
Your OpenAPI generation is now:
- ⚡ Faster - Less code to write
- 🎯 More accurate - Paths derived from file structure
- 🔧 Easier to maintain - Single source of truth
- 🚀 More scalable - Adding routes is trivial
- ✅ Type-safe - Full TypeScript support
- 📚 Better documented - Metadata lives with code
Welcome to convention-based OpenAPI generation! 🎉