AdonisJS v7 一次把三件大事落地:从路由到 ORM 的端到端类型安全、零配置即可启用的 OpenTelemetry 可观测性、以及重新设计的起步套件。整个发布涉及 45+ 个包更新、3 个全新包,并把运行门槛抬到了 Node.js 24——直接用上原生 fetch、WebSocket 等 API,不再 shim。如果你一直在等一个"全栈 TypeScript 框架终于把类型串通"的节点,v7 就是那个节点。
类型安全终于从路由串到了数据库
过去在 AdonisJS 里,路由参数、请求体、查询结果各自类型独立,手动对齐是日常苦工。v7 把这条链路打通了:
- 路由定义时声明参数类型,控制器方法签名自动推断。
- Lucid ORM 模型的字段类型直接流入查询返回值。
- 响应体也可以通过
TypedContent新包做结构化输出校验。
这意味着从 router.get('/users/:id', ...) 到 User.find(id) 到返回 JSON,整条链路的 TypeScript 编译器都能帮你守门,不再靠运行时意外报错才发现字段名拼错。
下面是一个最小可运行的端到端类型安全示例——从路由到控制器到 ORM:
// app/controllers/users_controller.ts
import { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
export default class UsersController {
// :id 在路由中声明为 number,ctx.params.id 自动推断为 number
public async show({ params, response }: HttpContext<{ id: number }>) {
const user = await User.find(params.id) // 返回 User | null
if (!user) {
return response.notFound({ message: 'User not found' })
}
return response.ok(user.serialize()) // serialize() 返回类型已知
}
}
// start/routes.ts
import router from '@adonisjs/core/services/router'
const UsersController = () => import('#controllers/users_controller')
// params 类型在路由层声明,控制器自动继承
router.get('/users/:id', [Controllers.UsersController, 'show'])
.where('id', router.matchers.number()) // 路由参数约束为 number
// app/models/user.ts
import { BaseModel, column } from '@adonisjs/lucid'
import { DateTime } from 'luxon'
export default class User extends BaseModel {
@column({ isPrimary: true })
declare id: number
@column()
declare email: string
@column.dateTime({ autoCreate: true })
declare createdAt: DateTime
}
三段代码拼在一起:路由约束 id 为 number → 控制器 params.id 推断为 number → User.find() 返回 User | null → serialize() 输出已知结构。编译器全程在线,漏字段或类型不匹配直接报红。
零配置 OpenTelemetry:可观测性不再是"后期补装"
v7 新增了 @adonisjs/otel 包,开箱即用,不需要手动拼接 exporter、provider、span processor。框架在 HTTP 请求生命周期、Lucid 查询、模板渲染等关键路径自动埋点,你只需决定数据往哪发。
启用方式极简:
# 安装 OpenTelemetry 包
npm install @adonisjs/otel
# 一次性配置(选择 exporter 类型等)
node ace configure @adonisjs/otel
配置完成后,config/otel.ts 里指定 exporter 即可。以下是一个把 trace 数据发到本地 Jaeger 的最小配置:
// config/otel.ts
import { defineConfig } from '@adonisjs/otel'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
export default defineConfig({
enabled: true,
exporter: new OTLPTraceExporter({
url: 'http://localhost:4318/v1/traces', // Jaeger OTLP HTTP endpoint
}),
// 采样率按环境调整,生产可改为 parentBased + probability
sampler: {
type: 'alwaysOn',
},
})
启动应用后,每个 HTTP 请求和数据库查询自动生成 span,无需在业务代码里手动 startSpan / endSpan。本地验证:
# 启动 Jaeger(Docker 一行搞定)
docker run -d --name jaeger \
-p 16686:16686 -p 4318:4318 \
jaegertracing/all-in-one:latest
# 启动 AdonisJS 应用
node ace serve --watch
# 发一个请求
curl http://localhost:3333/users/1
# 打开 Jaeger UI 查看自动生成的 trace
# http://localhost:16686
从安装到看到 trace,中间没有写任何手动埋点代码。这对小团队尤其关键——可观测性不再是"上线后再补"的奢侈品。
起步套件重构与 Node.js 24 门槛
v7 的起步套件(starter kits)做了大幅重组,把"先装什么、后装什么"的决策成本压低:
- web 套件:路由 + Lucid ORM + 认证 + session + Edge 模板,适合传统全栈应用。
- api 套件:路由 + Lucid + 认证 + JWT/API token,不含模板,适合前后端分离。
- slim 套件:仅核心 HTTP + 路由,其余自己拼,适合微服务或定制化项目。
创建项目一行命令:
# 需要 Node.js 24+
node --version # 确认 >= 24.0.0
# 创建 api 套件项目
npm create adonisjs@latest my-api-app -- --kit=api
# 或 web 套件
npm create adonisjs@latest my-web-app -- --kit=web
Node.js 24 的硬性要求意味着你可以直接用原生 fetch 替代 node-fetch、用原生 WebSocket 替代第三方库、用 fs.promises 不再 polyfill。框架内部也清理了大量 shim 代码,包体积和启动速度都有收益。代价是:如果你的部署环境还停在 Node 20/22,v7 暂时上不了。
上手清单与取舍判断
在决定是否把项目迁到 AdonisJS v7 之前,几条务实考量:
- Node.js 24 是否就绪? 查你的 CI/CD 和生产运行环境。如果还在 Node 20 LTS 周期里,v7 需要等环境升级。本地开发可以用
nvm install 24先试。 - 类型安全收益有多大? 如果你的项目已经大量使用 Lucid 模型且字段频繁变动,端到端类型推断会直接减少运行时 bug。如果只是简单 CRUD,收益相对温和。
- OpenTelemetry 是否在路线图上? 如果团队还没任何 trace 基础设施,v7 的零配置 OTel 是最低成本起步点——先跑 Jaeger 本地看效果,再决定是否上云端 exporter。如果已有自定义埋点体系,需要评估
@adonisjs/otel的自动 span 是否与你现有逻辑冲突。 - 起步套件选哪个? 新项目直接按场景选 web/api/slim。迁移项目建议 slim 套件逐步引入模块,避免一次性重写。
快速验证 v7 全链路体验的完整步骤:
# 1. 确认 Node 版本
nvm install 24 && nvm use 24
# 2. 创建 slim 项目(最小依赖,方便试类型安全)
npm create adonisjs@latest adonisv7-demo -- --kit=slim
# 3. 进入项目,安装 Lucid ORM 和 OpenTelemetry
cd adonisv7-demo
npm install @adonisjs/lucid @adonisjs/otel
node ace configure @adonisjs/lucid # 选 SQLite 本地试
node ace configure @adonisjs/otel
# 4. 创建一个模型和路由,验证类型推断
node ace make:model User
node ace make:controller UsersController
# 5. 启动 + 发请求 + 看 trace
node ace serve --watch
curl http://localhost:3333/users/1
AdonisJS v7 不是渐进式小升级——它把类型安全、可观测性、运行时基础三件事同时推到了一个新基线。如果你的技术栈正好卡在这些痛点上,现在是认真评估的时机。