@flowcore/hono-api

中文文档
0.4.1发布于 2026/09/01MITTypeScriptESM + CJS近 30 天下载 6235

Flowcore Hono API 构建器

中文使用文档
文档目录12 节
  1. OpenTeleometry Track-Log 关联
  2. QQ 正确的设置
  3. 常见错误
  4. 环境变量
  5. 全球JWT配置
  6. QQ 全球 JWT 配置
  7. JWT 配置接口
  8. OIDC 提供方实例
  9. 福利
  10. 使用量
  11. 测试
  12. 测试范围

Flowcore Hono API 构建器

OpenTeleometry Track-Log 关联

追踪和记录的关联性, 启动命令至关重要数字 :

QQ 正确的设置

// main.ts - FIRST THING IN APPLICATION
import init from "@flowcore/hono-api/otel"

// Initialize OTEL before any other imports
init({
  otelServiceName: "my-api",
  otelEndpoint: "http://localhost:4318", // OTLP HTTP endpoint
  runtime: "bun" // or "node" | "deno"
})

// Now safe to import and use the library
import { HonoApi, HonoApiRouter, loggerFactory } from "@flowcore/hono-api"
import { z } from "@hono/zod-openapi"

// Create logger with trace correlation
const createLogger = loggerFactory({
  prettyPrintLogs: true,
  logLevel: "info"
}).createLogger

const logger = createLogger("main")

// Your logs will now include trace_id and span_id automatically
logger.info("Application starting", { port: 3000 })

常见错误

// WRONG: Creating logger before OTEL initialization
import { loggerFactory } from "@flowcore/hono-api"
const logger = loggerFactory(...).createLogger("main") // No trace correlation!

import init from "@flowcore/hono-api/otel"
init({ ... }) // Too late - logger already created

环境变量

变量类型说明默认需求
OTEL 服务 NAME字符串追踪服务名称- 说吧✓
OTEL 出口 OTLP ENDPOINT字符串OTLP 端点 URL- 说吧✓

全球JWT配置

支持 HonoApi 全球JWT配置 用于自定义的 OIDC 供应商,如 Keycloak, Okta, 或 Auth0. 这就不需要每个路由配置JWT验证.

QQ 全球 JWT 配置

import { HonoApi, JWTValidationConfig, FLOWCORE_JWT_CONFIG } from "@flowcore/hono-api"
import { z } from "@hono/zod-openapi"

// Custom JWT configuration for Keycloak
const keycloakConfig: JWTValidationConfig = {
  extractUserId: (payload) => payload.sub as string,
  extractEmail: (payload) => payload.email as string,
  extractIsAdmin: (payload) => {
    const roles = payload.realm_access?.roles || []
    return roles.includes("admin")
  },
  validatePayload: (payload) => {
    if (!payload.sub) {
      throw new Error("Missing subject in JWT")
    }
    if (!payload.email_verified) {
      throw new Error("Email not verified")
    }
  }
}

// Option 1: Global config via auth.jwtConfig
const api = new HonoApi({
  auth: {
    jwks_url: "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/certs",
    jwtConfig: keycloakConfig
  }
})

// Option 2: Global config via authDefaults (takes precedence)
const api = new HonoApi({
  auth: {
    jwks_url: "https://your-keycloak.com/realms/your-realm/protocol/openid-connect/certs",
  },
  authDefaults: {
    jwtConfig: keycloakConfig,
    optional: true // Apply to routes without explicit auth config
  }
})

JWT 配置接口

interface JWTValidationConfig {
  extractUserId: (payload: JWTPayload) => string
  extractEmail?: (payload: JWTPayload) => string | undefined  
  extractIsAdmin?: (payload: JWTPayload) => boolean
  validatePayload?: (payload: JWTPayload) => void
}

OIDC 提供方实例

Keycloak 配置 :

const keycloakConfig: JWTValidationConfig = {
  extractUserId: (payload) => payload.sub as string,
  extractEmail: (payload) => payload.email as string,
  extractIsAdmin: (payload) => {
    const realmRoles = payload.realm_access?.roles || []
    return realmRoles.includes("admin")
  }
}

Auth0 配置 :

const auth0Config: JWTValidationConfig = {
  extractUserId: (payload) => payload.sub as string,
  extractEmail: (payload) => payload.email as string,
  extractIsAdmin: (payload) => {
    const roles = payload["https://myapp.com/roles"] || []
    return roles.includes("admin")
  }
}

Okta 配置 :

const oktaConfig: JWTValidationConfig = {
  extractUserId: (payload) => payload.uid as string,
  extractEmail: (payload) => payload.email as string,
  extractIsAdmin: (payload) => {
    const groups = payload.groups || []
    return groups.includes("Administrators")
  }
}

福利

  • ✅ 没有每道配置 - JWT配置适用于全球
  • ✅ OIDC 供应商的灵活性 - 支持任何JWT发行商
  • ✅ 后向兼容性 - Flowcore 认证在默认情况下仍然有效
  • ✅ 自定义验证 - 在JWT验证中添加商业逻辑
  • ✅ 基于角色的接入 - 从JWT索赔中提取管理/用户角色

使用量

import { HonoApi, HonoApiRouter } from "../src/mod.ts"
import { z } from "@hono/zod-openapi"

// root-router.ts
const rootRouter = new HonoApiRouter()
rootRouter.get("/health", {
  tags: ["root"],
  auth: {
    optional: true,
  },
  output: z.object({
    status: z.enum(["ok", "error"]).openapi({
      example: "ok",
    }),
  }),
  handler: () => {
    return {
      status: "ok" as const,
    }
  },
})

// data-cores-router.ts
const apiV1DataCoreRouter = new HonoApiRouter()
apiV1DataCoreRouter.post("/", {
  summary: "Create a data core",
  description: "Create a data core",
  tags: ["data-core"],
  auth: {
    permissions: (input) => {
      return [{
        action: "write",
        resource: [`frn::${input.body.tenantId}:data-core:*`],
      }]
    },
  },
  input: {
    body: z.object({
      name: z.string().openapi({
        example: "my-data-core",
      }),
      tenantId: z.string().openapi({
        example: "00000000-0000-0000-0000-000000000000",
        description: "The ID of the tenant to create the data core on",
      }),
    }),
  },
  output: z.object({
    id: z.string(),
    name: z.string(),
    tenantId: z.string(),
  }),
  handler: (input) => {
    return {
      id: crypto.randomUUID(),
      name: input.body.name,
      tenantId: input.body.tenantId,
    }
  },
})

// Hono API
const honoApi = new HonoApi({
  // Auth is optional (These are the defaults)
  auth: {
    jwks_url: "https://auth.flowcore.io/realms/flowcore/protocol/openid-connect/certs",
    api_key_url: "https://iam.api.flowcore.io",
    iam_url: "https://iam.api.flowcore.io",
  },
  // OpenAPI is optional (These are the defaults)
  openapi: {
    docPath: "/swagger",
    jsonPath: "/swagger/openapi.json",
    version: "0.0.1",
    name: "Hono API",
    description: "Hono API",
  },
  // Logger is optional (This is the default)
  logger: console,
})

honoApi.addRouter("/", rootRouter)
honoApi.addRouter("/api/v1/data-cores", apiV1DataCoreRouter)

// Serve your api in your preferred manner
Deno.serve({ port: 3000 }, honoApi.app.fetch)

Bun.serve({
  port: 3000,
  fetch: honoApi.app.fetch
})

测试

该项目包括对API功能的全面测试:

# Run all tests
deno task test

# Run tests in watch mode
deno task test:watch

# Run tests with coverage
deno task test:coverage

# Type check all files
deno task typecheck

测试范围

测试套房包括:

  • HonoApi 类: 初始化、配置、路由器安装、请求处理
  • 胡诺阿皮鲁特级: 路由注册,路径处理,HTTP方法,配置
  • 例外类别: 所有有适当状态代码和序列化的错误类型
  • 请求/答复处理获取, POST, PUT, PATCH, DEELETE 方法
  • 输入验证: 标题、查询参数、路径参数、请求机构
  • OpenAPI 文档: 提供光谱生成和文献服务
  • 普罗米修斯量子: 计量收集和端点保护
  • 处理错误: 内部服务器错误和自定义例外

认证测试按要求排除在外,但必要时可以单独添加.

版本与发布记录

@flowcore/hono-api 共发布 36 个版本,首次发布于 2025/05/13;过去 12 个月发布了 2 个版本。

版本发布日期距今
0.4.1latest2026/09/012 个月前
0.4.02026/07/064 个月前
0.3.02025/07/241.3 年前
0.2.02025/07/231.3 年前
0.1.92025/06/171.4 年前
0.1.82025/06/171.4 年前

关于 @flowcore/hono-api 的常见问题

@flowcore/hono-api 是什么?

Flowcore Hono API 构建器

如何安装 @flowcore/hono-api?

在项目目录运行 npm install @flowcore/hono-api,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^3.25.63)、@flowcore/pathways(^0.16.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@flowcore/hono-api 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@flowcore/hono-api 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@flowcore/hono-api 可以商用吗?

@flowcore/hono-api 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@flowcore/hono-api 的下载量有多少?

根据 npm 官方下载统计,@flowcore/hono-api 在 2026/10/15 – 2026/11/13 这 30 天内被下载 6,235 次,日均约 208 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@flowcore/hono-api 还在维护吗?

最新版本 0.4.1 发布于 2026/09/01(2 个月前);至今共发布 36 个版本,其中过去 12 个月发布了 2 个;首次发布于 2025/05/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。