npm package: @seepine/hono-router
Description: Hono route loader with OpenAPI and Swagger support — load routes from files and generate OpenAPI docs using Zod schemas.
Author: seepine
Latest version: 0.1.1

# hono-router

[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![License][license-src]][license-href]

基于 [Hono](https://hono.dev/) 的路由加载工具，支持从文件（或 glob）加载路由配置、基于 Zod 生成 OpenAPI Schema，并集成 Swagger UI。

主要特性：

- 自动从文件模块加载路由并注册到 Hono 应用
- 使用 Zod schema 生成 OpenAPI 文档（依赖 `@hono/zod-openapi`）
- 内置请求/响应校验，支持自定义路由配置
- 集成 Swagger UI 展示 API 文档

## 快速上手

### 安装

```bash
npm install @seepine/hono-router
```

同时安装依赖：

```bash
npm install hono @hono/zod-openapi zod
```

## 加载路由

### 手动加载

手动传入 `Route[]` 数组

```ts
import { OpenAPIHono } from '@hono/zod-openapi'
import { loadRouter, defineRoute } from '@seepine/hono-router'

// 注意，此处使用 OpenAPIHono，而非 Hono
const app = new OpenAPIHono()

// 加载路由
await loadRouter(app, [
  {
    path: 'health',
    handler: () => {
      return { ok: true }
    },
  },
])

export default app
```

### 自动加载路由

例如我们指定一个目录 `src/routes` 存放所有路由，假设我们创建了一个接口 `src/routes/health.ts`

```ts
export default defineRoute({
  handler(c, req) {
    return { status: 'ok' }
  },
})
```

可以通过glob扫描并加载路由

```ts
import { globSync } from 'tinyglobby'

const routesDir = 'src/routes'
const routes: GlobRoute[] = []
for (const file of globSync(`${routesDir}/**/*.{js,ts}`)) {
  // file = src/routes/user/add.ts
  let relativePath = file.replace(routesDir + '/', '')
  routes.push({
    relativePath, // relativePath = user/add.ts
    module: await import(file),
  })
}
// 动态加载所有路由
loadRoutes(app, routes)
```

最终会自动注册接口 `/health`

## 路由用法

### 普通路由

```ts
// 可指定路径和方式
export default defineRoute({
  path: 'user/:id',
  method: 'GET',
  handler: (c, req) => {
    return { id: req.params.id }
  },
})
```

### 单文件多路由

若觉得创建多个文件繁琐，可在 `user.ts` 中定义所有相关路由

```ts
const getById = defineRoute({
  path: 'getById',
  method: 'GET',
  handler: (c, req) => {
    return { id: req.params.id }
  },
})

const add = defineRoute({
  path: 'add',
  method: 'POST',
  handler: (c, req) => {
    return { id: req.params.id }
  },
})

// 若通过GlobRoute注册，则会生成如下路由
//   GET /user/getById
//   POST /user/add
export default [getById, add]
```

### 绝对路由

默认 `path` 若是相对路径，会再拼接上文件目录组成 URL，例如创建了路由文件 `sys/user.ts`

```ts
// 可指定路径和方式
export default defineRoute({
  path: 'add', // 则接口为 /sys/user/add
  path: '/add', // 则接口为 /add
  method: 'GET',
  handler: (c, req) => {
    return { id: req.params.id }
  },
})
```

### 定义 schema

```ts
defineRoute({
  schema: {
    operationId: 'getById',
    request: {
      params: z.object({
        id: z.string(),
      }),
    },
  },
  handler: (c, req) => {
    // 此时params会有类型推导
    return { id: req.params.id }
  },
})
```

### 路由 config

```ts
defineRoute({
  // 设置任意值给config
  config: {
    auth: false,
  },
  handler: (c, req) => {
    return { id: req.params.id }
  },
})

app.use(
  createMiddleware(async (c, next) => {
    // 通过 import { routeConfig } from '@seepine/hono-router'
    console.log('route config', routeConfig(c))
    // { auth: false }
    await next()
  }),
)
```

更多示例参见源码中的 `src` 文件：

- `loadRouter`：加载并注册路由，支持 `basePath`、OpenAPI 与 Swagger UI 开关等配置
- `defineRoute`：类型化路由定义，用于更清晰地编写路由模块
- `getConfig`：在中间件中获取当前路由配置

## 配置项

`loadRouter` 接受第三个参数 `routerOpts`，常见选项如下：

- `basePath`：基础路径（例如 `/api`）
- `openAPIEnable`：是否启用 OpenAPI 文档（默认 `true`）
- `swaggerUIEnable`：是否启用 Swagger UI（默认 `true`）
- `defaultMethods`：默认方法列表（默认 `['GET','POST','DELETE','PUT','PATCH']`）
- `log`：日志函数，默认 `console.log`

## Swagger UI

当 `openAPIEnable` 与 `swaggerUIEnable` 均为 `true` 时，`loadRouter` 会在 `basePath + '/swagger'` 提供 Swagger UI 页面，OpenAPI 文档位于 `basePath + '/docs'`。

## 贡献

欢迎 PR、Issue 与改进建议。

<!-- Refs -->

[npm-version-src]: https://img.shields.io/npm/v/@seepine/hono-router
[npm-version-href]: https://www.npmjs.com/package/@seepine/hono-router
[npm-downloads-src]: https://img.shields.io/npm/dm/@seepine/hono-router
[npm-downloads-href]: https://npmjs.com/package/@seepine/hono-router
[bundle-src]: https://img.shields.io/bundlephobia/minzip/@seepine/hono-router
[bundle-href]: https://bundlephobia.com/result?p=@seepine/hono-router
[license-src]: https://img.shields.io/github/license/seepine/hono-router.svg
[license-href]: https://github.com/seepine/hono-router/blob/main/LICENSE