下面我们给API添加创建功能。
添加路径
修改文件 app/api/[[...route]]/routes/tasks/tasks.routes.ts
:
1 | ... |
下面我们给API添加创建功能。
修改文件 app/api/[[...route]]/routes/tasks/tasks.routes.ts
:
1 | ... |
之前用下面的Schema创建了表:
1 | export const tasks = sqliteTable("tasks", { |
发现这个创建时间和更新时间并没有生效,研究了一下,这样写可能有问题。
查询了一下,修改为下面的语句:
1 | import { sql } from "drizzle-orm"; |
updateAt字段无效,需要更新时主动更新。
修改完后,利用 drizzle-kit 重新生成数据库:
1 | bun drizzle-kit generate |
试了一下,插入数据后自动产生了时间:
1 | 1|Hello Hone|0|2025-02-24 06:13:34|2025-02-24 06:13:34 |
之前API的实现只是简单的返回固定值,本章开始实行数据库读写。
Drizzle ORM 是用于 SQL 数据库的 TypeScript ORM,在设计时考虑到了最大的类型安全性。它带有用于自动生成 SQL 迁移的 drizzle-kit CLI 。Drizzle ORM 是一个库,而不是一个框架,它的主要哲学是 “如果你知道 SQL,你就知道 Drizzle ORM”,因此设计的时候尽可能遵循类似 SQL 的语法,强类型化并在编译时就会失败,而不是在运行时。
安装 Drizzle, Drizzle 的安装根据支持的数据库,命令略有不同,这里我们采用 SQLite , 命令如下:
1 | bun add drizzle-orm @libsql/client dotenv |
注:drizzle-zod 是Zod搭配drizzle的一个包,后面会用到。
修改 utility/env.ts
:
1 | import { z } from "zod"; |
上一篇我们创建了 api/节点,这次我们继续创建子节点,通过在Routes路径下创建子目录和文件实现。
首先, 添加 app/api/[[...route]]/routes/tasks/tasks.index.ts
:
1 | import { createRouter } from "../../lib/create-app"; |
这个文件作为索引文件,链接了handler和router两个文件,我们来创建它们。
More...添加 app/api/[[...route]]/lab/configure-openapi.ts
:
1 | import type { AppOpenAPI } from "@/utility/types"; |
修改 app/api/[[...route]]/route.ts
,添加调用:
1 | ... |
访问 网址 localhost:3001/api/doc,显示如下:
Zod 是一个 TypeScript 优先的模式声明和验证库。我使用术语 “模式” 来广义地指任何数据类型,从简单的 字符串 到复杂的嵌套对象。Zod 围绕尽可能友好的开发体验而设计。其目的是消除重复的类型声明。使用 Zod,你只需声明 一次 验证器,Zod 就会自动推断出静态 TypeScript 类型。将简单类型组合成复杂的数据结构非常容易。我的理解,它补足了 Typescript 在动态类型检查上的缺陷,让程序可以更稳定的运行,减少因为类型不匹配导致的问题。
可以用 bun add zod
安装,但实际上我们之前因为依赖,已经安装过了。
创建文件 utility/env.ts
:
1 | import { z } from "zod"; |
其他代码中用到 process.env.xxx
都改成 env.xxx
Pino 是一个非常快速且简洁的 Node.js 日志库,其设计宗旨在于提供最小的开销以及高性能的日志记录功能。下面我们来在项目中搭建它。
安装:
1 | bun add hono-pino pino |
代码实现:
添加文件:middlewares/pino-logger.ts
:
1 | import { pinoLogger } from 'hono-pino'; |
运行程序:bun run dev
访问localhost,返回 “Hello Hono”,同时控制台显示:
在项目目录下创建文件:app/api/[[...route]]/route.ts
:
1 | import { Hono } from "hono"; |
运行程序:bun run dev
访问localhost,返回 “Hello Hono”,同时控制台显示:
1 | Server running on port 3001 |
你是否曾经遇到过这样的 API 文档,其中每一个端点(endpoint)都被详细记录,你可以深入了解所有可能的响应类型,并查看它们的示例。同时,它们还包含模式(schemas),你甚至可以进入并测试这些特定的端点,实际运行并访问 API,设置请求头和其他细节。从这个文档开始,我将从头开始构建一个使用 Hono 的 API,并使用 OpenAPI 规范来全面记录我们的 API。因此,如果你访问 /doc,你会看到每一个端点都被记录在案。OpenAPI 实际上是一个工具生态系统,可以利用这些文档创建互动文档,或者生成客户端库及其他类似的东西。我一直在使用 Hono 构建应用程序,特别是我一直在使用他们的中间件 Zod OpenAPI,该中间件基本上允许你使用 Zod 来定义所有的模式(schemas),然后定义你的路由合约,并使用这些路由合约在定义请求处理程序时获得类型安全。所有这些最终都被转化为完全互动的文档。
首先,我会使用NextJS和Hono搭建后台API。NextJS不用多介绍,它是一个用于构建全栈Web 应用的React 框架。Hono是一个小巧、简单且超快速的 Web 框架,构建在 Web 标准之上,号称可以在任何 JavaScript 运行时环境中运行,包括 Cloudflare Workers、Fastly Compute、Deno、Bun、Vercel、Netlify、AWS Lambda、Lambda@Edge 和 Node.js。
在设置 OpenAPI 时,我们也可以以一种可扩展的方式进行。例如,我们可以在一个地方设置所有的路由定义,然后在另一个地方设置所有的处理程序,但一切依然是类型安全的。我们实际上会导出这些路由定义的类型,并且可以使用它们来定义我们的请求处理程序。这样,我们可以在一个单独的文件中定义我们的处理程序,但仍然具有完整的类型安全性,这意味着我们准确知道对于这个特定的方法基于这个特定的路由我们应该响应什么。
除此之外,Hono 使得测试这些端点变得非常容易,因为他们有一个内置的测试客户端,本质上类似于 Hono RPC 客户端,可以在客户端代码中使用,并具有完全的类型安全性,但它也是一个非常好的测试体验。
此外,我们可以将其与 Drizzle 连接起来,Drizzle Zod 基本上允许我们定义我们的表,然后使用这些表定义来定义我们的 Zod 模式(schemas),然后我们可以直接在我们的 OpenAPI 定义中使用这些模式。因此,我们基本上有一个单一的事实来源,我们可以定义我们的表,得到我们的模式,然后在我们的路由定义中使用这些模式,从那时起,当我们定义处理程序时,所有类型都会流转。
其次,我使用了一些现成的库 stoker 和样板库 hono-open-api-starter 来减少代码量,当然你也可以直接自己实现。
More...作为一名开发者,都需要编写程序的 API 文档。现代开发框架,都需要API的协作,有时完成一个操作,需要调用多个API才能完成,所以,一个好的 API 文档能够大大提高协作效率,降低沟通成本。为解决API文本规范的问题,我们聊聊如何使用 OpenAPI 构建 HTTP 接口文档。
OpenAPI 是规范化描述 API 领域应用最广泛的行业标准,由 OpenAPI Initiative(OAI) 定义并维护,同时也是 Linux 基金会下的一个开源项目。通常我们所说的 OpenAPI 全称应该是 OpenAPI Specification(OpenAPI 规范,简称 OSA),它使用规定的格式来描述 HTTP RESTful API 的定义,以此来规范 RESTful 服务开发过程。使用 JSON 或 YAML 来描述一个标准的、与编程语言无关的 HTTP API 接口。OpenAPI 规范最初基于 SmartBear Software 在 2015 年捐赠的 Swagger 规范演变而来,目前最新的版本是 v3.1.1。本文参考了apifox 发布的一个 中文版。
一份 OpenAPI 文档可以是单个文件也可以被拆分为多个文件, 连接的部分由用户自行决定。在后一种情形下,必须如 JSON Schema 中定义的那样使用 $ref
字段来相互引用。
推荐将根 OpenAPI 文档命名为openapi.json
或 openapi.yaml
。
请我喝杯咖啡吧~