Status: Experimental
@blgc/openapi-router
is a thin wrapper around the router of web frameworks like Express and Hono, offering OpenAPI typesafety and seamless integration with validation libraries such as Valibot and Zod.
- Typesafe: Build with TypeScript for strong type safety and support for
openapi-typescript
types - Framework Agnostic: Compatible with Express, Hono, and other popular web frameworks
- Validation-First: Integrates with Valibot, Zod, and other validators to ensure requests adhere to expected types
- Modular & Extendable: Easily extendable with features like
withExpress()
, ..
Create a typesafe and straightforward wrapper around web framework routers, seamlessly integrating with OpenAPI schemas using openapi-typescript
and ensuring type validation with libraries like Zod and Valibot.
import { createExpressOpenApiRouter } from '@blgc/openapi-router';
import express, { Router } from 'express';
import * as v from 'valibot';
import { vValidator } from 'validation-adapters/valibot';
import { paths } from './path/to/openapi/types';
const app = express();
app.use(express.json());
const router = Router();
const openapiRouter = createExpressOpenApiRouter<paths>(router);
openapiRouter.get('/pet/{petId}', {
pathValidator: vValidator(
v.object({
petId: v.number()
})
),
handler: async (req, res, next) => {}
});
openapiRouter.get('/pet/findByTags', {
queryValidator: vValidator(
v.object({
tags: v.optional(v.array(v.string()))
})
),
handler: (req, res, next) => {}
});
app.use('/*', router);
Hono's TypeScript integration provides type suggestions for
c.json()
based on generically defined response types, but doesn't enforce these types at compile-time. For example,c.json('')
won't raise a type error even if the expected type is{someType: string}
. This is due to Hono's internal use ofTypedResponse<T>
, which infers but doesn't strictly enforce the passed generic type. Hono Discussion
import { createHonoOpenApiRouter } from '@blgc/openapi-router';
import { Hono } from 'hono';
import * as v from 'valibot';
import { vValidator } from 'validation-adapters/valibot';
import { paths } from './path/to/openapi/types';
export const app = new Hono();
const router = new Hono();
const openapiRouter = createHonoOpenApiRouter<paths>(router);
openapiRouter.get('/pet/{petId}', {
pathValidator: vValidator(
v.object({
petId: v.number()
})
),
handler: async (c) => {}
});
openapiRouter.get('/pet/findByTags', {
queryValidator: vValidator(
v.object({
tags: v.optional(v.array(v.string()))
})
),
handler: (c) => {}
});
// Application endpoint
app.route('/', router);