The OpenAPI Loader V2 represents a complete rewrite of the custom OpenAPI implementation using the official @hono/zod-openapi library. This migration dramatically simplifies the codebase and provides better type safety and maintainability.
- Before: 1,445 lines of custom OpenAPI implementation
- After: ~570 lines using the official library
- Reduction: ~60% less code to maintain
- Native TypeScript support with
@hono/zod-openapi - Automatic validation with detailed error messages
- Type-safe request/response handling
- Active maintenance by the Hono team
- Regular updates and bug fixes
- Better compatibility with the Hono ecosystem
- Route definitions are declarative and easy to understand
- Separation of concerns between routes and handlers
- Built-in OpenAPI documentation generation
// Complex custom OpenAPI parsing
export class OpenAPILoader {
private spec: OpenAPISpec | null = null;
private routes: Map<string, RouteConfig> = new Map();
// 1,445 lines of custom implementation
async loadSpec(specPath: string): Promise<void> {
// Manual JSON parsing
// Custom route generation
// Complex validation middleware
// Manual security scheme parsing
}
}
// Simple, declarative route definitions
const loader = createOpenAPILoaderV2({
title: "ZenServer API",
version: "1.0.0",
description: "Secure payment and tour booking API"
});
// Clean route definition
const route = createRouteDefinition('post', '/api/v1/create-nonce', 'createPaymentNonce', {
summary: 'Create payment nonce',
tags: ['Payment'],
security: [{ type: 'rateLimit', required: true }],
body: z.object({
amount: z.number().min(0.01),
currency: z.string().length(3)
}),
responses: {
200: {
description: 'Payment nonce created successfully',
schema: z.object({
nonce: z.string(),
expiresAt: z.string().datetime()
})
}
}
});
| Feature | V1 (Custom) | V2 (@hono/zod-openapi) |
|---|---|---|
| Code Size | 1,445 lines | ~570 lines |
| Type Safety | Manual typing | Native TypeScript |
| Validation | Custom Zod conversion | Built-in validation |
| Documentation | Manual spec generation | Automatic OpenAPI docs |
| Maintenance | High (custom code) | Low (official library) |
| Error Handling | Custom error responses | Standardized errors |
| Security | Manual security parsing | Built-in security schemes |
| Route Definition | Complex configuration | Declarative definitions |
# Already available in Val Town # @hono/zod-openapi@0.19.9 is imported via esm.sh
// Old way
import { OpenAPILoader } from "./openApiLoader.ts";
const loader = new OpenAPILoader();
await loader.loadSpec("./openapi.json");
// New way
import { createOpenAPILoaderV2 } from "./openApiLoaderV2.ts";
const loader = createOpenAPILoaderV2({
title: "Your API",
version: "1.0.0"
});
// Old: Routes defined in JSON spec file
// New: Routes defined in TypeScript code
const routes = [
createRouteDefinition('get', '/health', 'healthCheck', {
summary: 'Health check',
responses: {
200: {
description: 'Server is healthy',
schema: z.object({
status: z.string(),
timestamp: z.string().datetime()
})
}
}
})
];
loader.registerRoutes(routes);
// Same pattern as before
const handlers = {
healthCheck: async (c) => {
return c.json({
status: 'healthy',
timestamp: new Date().toISOString()
});
}
};
loader.registerHandlers(handlers);
// Export the configured app
const app = loader.getApp();
export default app.fetch; // For Val Town
V1: Routes defined in separate JSON file, complex parsing V2: Routes defined in TypeScript with full type safety
V1: Custom Zod schema conversion with manual middleware V2: Built-in validation with automatic error responses
V1: Manual OpenAPI spec generation
V2: Automatic OpenAPI documentation at /openapi.json
V1: Complex security scheme parsing from descriptions V2: Built-in security schemes with proper typing
V1: Custom error responses and logging V2: Standardized error responses with proper HTTP status codes
- Faster route creation with declarative syntax
- Immediate feedback with TypeScript types
- No need to maintain separate JSON specs
- Request/response types are automatically inferred
- Validation errors are type-safe
- No runtime type mismatches
- 60% less code to maintain
- Official library handles edge cases
- Regular updates from Hono team
- Automatic OpenAPI spec generation
- Always up-to-date documentation
- Interactive API docs possible
- Easier to test individual routes
- Type-safe mocking
- Better error messages
- Create new OpenAPI Loader V2 instance
- Convert route definitions from JSON to TypeScript
- Update handler signatures to use proper Context types
- Test all endpoints with new validation
- Verify OpenAPI documentation generation
- Update middleware to work with new loader
- Remove old OpenAPI loader and JSON files
- Update deployment scripts if needed
- Import using
https://esm.sh/@hono/zod-openapi@0.19.9 - Export
app.fetchfor Val Town compatibility - All existing handlers should work with minimal changes
- Existing security middleware will continue to work
- Security schemes are now properly typed
- Better integration with Hono's middleware system
- Phase 1: Create V2 loader alongside V1 for testing
- Phase 2: Convert a few endpoints to V2 format
- Phase 3: Test thoroughly in development
- Phase 4: Migrate all endpoints to V2
- Phase 5: Remove V1 loader and cleanup
The OpenAPI Loader V2 represents a significant improvement in:
- Code maintainability (60% reduction)
- Type safety (native TypeScript)
- Developer experience (declarative definitions)
- Long-term sustainability (official library)
The migration provides immediate benefits and sets up the codebase for future growth with proper typing and modern tooling.