ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

在 Convex 中编写 Query 与 Mutation 函数:基于 tsgo-test 示例的完整实战指南

在 Convex 中编写 Query 与 Mutation 函数:基于 tsgo-test 示例的完整实战指南 数据库后端【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址https://gitcode.com/gh_mirrors/co/convex-backend点击查看免费下载导读本文以开源仓库 convex-backend 中npm-packages/private-demos/tsgo-test演示项目为背景完整讲解 Convex 函数Functions目录的标准组织方式如何编写带参数校验Validator的 query 与 mutation 函数、如何在 React 客户端调用它们、如何通过 Convex CLI 将函数推送到部署环境以及如何用 TypeScript 7 原生编译器 tsgo 对函数进行类型检查。读完本文你将掌握一套可直接复制到任何 Convex 项目中的最小可运行函数代码骨架并理解其背后 CLI 类型检查的实现原理。一、Convex 函数目录是什么在 Convex 应用中服务端代码存放在项目的convex/目录中即函数目录。这个目录里的每个 TypeScript/JavaScript 文件都会被打包并在 Convex 的云端或自托管后端中执行构成应用的服务端逻辑。以仓库中的npm-packages/private-demos/tsgo-test/convex/目录为例其标准结构包含README.md官方生成的函数目录说明模板即本文依据的核心文档example.ts一个最小可运行的 query 函数示例_generated/由npx convex dev自动生成的类型与 API 绑定代码api.ts、server.ts、dataModel.ts等tsconfig.json用于对 Convex 函数做类型检查的 TypeScript 工程配置。_generated目录是自动生成、不应手工修改的。在 server.d.ts 文件头部明确写着THIS CODE IS AUTOMATICALLY GENERATED. To regenerate, runnpx convex dev.其中导出了query、mutation、action、internalQuery、internalMutation、httpAction等全部服务端函数构造器以及QueryCtx、MutationCtx、DatabaseReader、DatabaseWriter等上下文类型。这些类型化的导出正是下面所有函数示例的类型安全基础。二、编写一个带参数校验的 query 函数2.1 函数定义骨架query 函数用于读取数据库是 Convex 中默认只读、可被客户端订阅的函数。官方模板给出的标准写法如下对应文档原文可在 README.md 中查看// convex/myFunctions.ts import { query } from ./_generated/server; import { v } from convex/values; export const myQueryFunction query({ // Validators for arguments. args: { first: v.number(), second: v.string(), }, // Function implementation. handler: async (ctx, args) { // Read the database as many times as you need here. const documents await ctx.db.query(tablename).collect(); // Arguments passed from the client are properties of the args object. console.log(args.first, args.second); // Write arbitrary JavaScript here: filter, aggregate, build derived data, // remove non-public properties, or create new objects. return documents; }, });拆解这个骨架有三个关键点args中的 Validator 是 Convex 的核心安全机制v.number()、v.string()来自convex/values包运行时会对客户端传入的每个参数做校验类型不匹配的函数调用会被直接拒绝从而避免脏数据进入数据库查询。除上述两种外v还提供v.id()、v.object()、v.array()、v.union()、v.optional()等完整校验器集合并支持.optional()链式写法。handler的第一个参数ctx是函数上下文ctx.db提供数据库访问能力。对 query 而言ctx.db的类型是只读的DatabaseReader见 server.d.ts只能get、query无法写入。handler可以写任意 JS 逻辑在返回前进行过滤、聚合、派生数据、剥离非公开字段等处理都是推荐做法——这相当于把数据脱敏与业务加工放在服务端完成。2.2 最小可运行示例仓库里的真实代码上述模板是教学示例仓库中tsgo-test演示项目实际部署了一个极简 query 函数见 example.tsimport { query } from ./_generated/server; export const hello query({ args: {}, handler: async (): Promisestring { return Hello from TypeScript!; }, });这个hello函数没有参数args: {}不做任何数据库访问直接返回一个字符串。它虽然简单却完整演示了 Convex 函数的最小闭环定义 → 生成 API 绑定 → 被客户端调用。在生成产物 api.d.ts 中可以看到api对象通过ApiFromModules自动收集了example模块下所有导出的函数引用客户端即可通过api.example.hello类型安全地调用它。2.3 在 React 中调用 queryConvex 为 React 提供了useQueryHook模板中的用法如下const data useQuery(api.myFunctions.myQueryFunction, { first: 10, second: hello, });useQuery会自动完成三件事订阅该查询、在数据变化时触发组件重新渲染、在组件卸载时取消订阅。它接收的参数对象与args中声明的 Validator 一一对应类型由_generated/api.d.ts从函数定义中推导因此参数写错会在编译期直接报错。三、编写一个带参数校验的 mutation 函数3.1 函数定义骨架mutation 函数用于写入数据库也可读取并具备原子性保证。官方模板如下// convex/myFunctions.ts import { mutation } from ./_generated/server; import { v } from convex/values; export const myMutationFunction mutation({ // Validators for arguments. args: { first: v.string(), second: v.string(), }, // Function implementation. handler: async (ctx, args) { // Insert or modify documents in the database here. // Mutations can also read from the database like queries. const message { body: args.first, author: args.second }; const id await ctx.db.insert(messages, message); // Optionally, return a value from your mutation. return await ctx.db.get(messages, id); }, });关键差异点ctx.db是读写类型DatabaseWriter除get、query外还提供insert、patch、replace、delete等写操作原子性保证单个 mutation 内的所有写入会被原子地提交见 server.d.ts 中DatabaseWriter的文档注释不会出现写了一半的中间状态也天然规避了乐观并发控制下的部分写问题可以返回值handler的返回值会被序列化后传回客户端便于客户端拿到刚插入文档的_id做后续跳转或 UI 更新。3.2 在 React 中调用 mutationmutation 在 React 中通过useMutationHook 调用模板给出了两种典型用法const mutation useMutation(api.myFunctions.myMutationFunction); function handleButtonPress() { // fire and forget, the most common way to use mutations mutation({ first: Hello!, second: me }); // OR // use the result once the mutation has completed mutation({ first: Hello!, second: me }).then((result) console.log(result), ); }Fire-and-forget推荐多数 UI 场景下不关心返回值直接调用即可Convex 客户端会负责把结果同步到所有订阅相关查询的组件获取结果mutation(...)返回 Promise.then()中拿到的正是服务端handler的返回值如上面示例中插入后重新读回的完整文档。四、推送函数与 CLI 工具链4.1 常用 CLI 命令函数写好后需要通过 Convex CLI 与部署环境交互。文档明确给出了两条基础命令查看 CLI 全部能力在项目根目录运行npx convex -h启动本地文档运行npx convex docs会打开本地/在线的 Convex 文档站点。实际开发中最常用的还有npx convex dev本地开发模式持续监听convex/目录自动完成代码生成_generated与函数推送并启动本地后端npx convex deploy将函数推送到生产部署npx convex codegen --init在缺少convex/tsconfig.json时创建类型检查所需的工程配置。4.2 CLI 的类型检查实现CLI 在每次推送前都会对函数目录执行 TypeScript 类型检查。仓库中的核心实现在 typecheck.ts编译器解析优先级resolveTypescriptCompiler第33-39行CLI 命令行参数 →convex.json中的typescriptCompiler字段 → 默认tsc类型检查模式TypeCheckMode第21行enable失败即中止推送、try找不到编译器时降级跳过、disable完全跳过通过--typecheckdisable启用检查入口读取convex/tsconfig.json若不存在则跳过并提示运行npx convex codegen --init第120-128行慢检查提示当单次类型检查超过 10 秒阈值SLOW_TYPECHECK_THRESHOLD_MS时CLI 会切换 spinner 并给出性能排查建议第25-27行、第69-73行。4.3 使用 tsgoTypeScript 7 原生编译器tsgo-test这个演示项目的特殊之处正是用tsgoTypeScript 原生编译器即 TypeScript 7 的 Native Preview替代传统tsc做类型检查。其配置链条如下①convex.json指定编译器见 convex.json{ typescriptCompiler: tsgo, $schema: https://raw.githubusercontent.com/get-convex/convex-backend/refs/heads/main/npm-packages/convex/schemas/convex.schema.json }②package.json声明 tsgo 依赖见 package.json{ name: tsgo-test, version: 0.0.0, scripts: { build: tsgo --noEmit -p convex/tsconfig.json }, dependencies: { convex: workspace:* }, devDependencies: { typescript/native-preview: ~7.0.0-dev.20251205.1 } }这里typescript/native-preview就是 tsgo 的 npm 发行包build脚本直接以tsgo --noEmit -p convex/tsconfig.json方式对函数目录做纯类型检查不产出文件因此该脚本也可作为 CI 中独立于 Convex CLI 的类型检查步骤。仓库的 turbo.json 进一步注明该任务的outputs为空即只检查、无产物。③ CLI 如何定位 tsgo 可执行文件在 typecheck.ts 的findTypeScriptCompilerPath中tsgo会依次查找node_modules/typescript/native-preview/bin/tsgo与bin/tsgo.js两个候选路径tsc则会兼容 TypeScript 6/7 并存的场景依次查找node_modules/typescript/native/bin/tsc与node_modules/typescript/bin/tsc。若找不到编译器二进制CLI 会以cantTypeCheck结果降级处理。④ 版本兼容性注意typescriptCompiler字段目前在convex.jsonschema 中已被标记为deprecated见 convex.schema.json 与 CHANGELOG.md。原因是 TypeScript 7 正式发布后Convex CLI 会自动探测并选用原生编译器无需再显式配置但tsgo-test这类依赖 Native Preview 开发版的旧项目仍可通过该字段保持显式指定两者兼容。4.4 函数目录的 tsconfig.json 要点convex/tsconfig.json描述了函数运行环境的 TypeScript 配置其注释明确区分了可修改与必需两组选项见 tsconfig.json可自由修改allowJs、strict、moduleResolution: Bundler、jsx、skipLibCheck、allowSyntheticDefaultImportsConvex 必需勿改target: ESNext、lib: [ES2023, dom]、forceConsistentCasingInFileNames、module: ESNext、isolatedModules、noEmitinclude/excludeinclude: [./**/*]覆盖全部函数源码exclude: [./_generated]排除自动生成目录避免与手工源码重复检查。五、从模板到生产函数开发的最佳实践要点综合官方模板README.md与仓库实现可以把 Convex 函数开发的关键实践总结为以下几条始终为args声明 Validator这是客户端输入的第一道防线也是客户端类型推导的数据源空参数也应显式写args: {}参考hello函数查询逻辑尽量收敛到 query写入逻辑收敛到 mutationquery 只读、可订阅、可被自动缓存mutation 原子写入二者职责分离能让 UI 保持实时一致服务端完成数据加工过滤敏感字段、聚合、派生计算放在 handler 中而不是让客户端拿到全量数据把convex/下的 README 模板当作速查手册模板中 query/mutation 的完整骨架、React 调用示例、CLI 命令提示覆盖了 80% 的日常开发场景用 tsgo/tsc 做独立类型检查可将tsgo --noEmit -p convex/tsconfig.json或tsc等价命令接入 CI与npx convex deploy内置的类型检查形成双保险。六、参考资料官方函数目录模板README.md最小 query 函数实现example.ts自动生成的类型绑定server.d.ts、api.d.ts编译器与工程配置convex.json、tsconfig.json、package.jsonCLI 类型检查实现typecheck.tstypescriptCompiler配置项 schemaconvex.schema.json赞分享数据库后端【免费下载链接】convex-backendThe open-source reactive database for app developers项目地址https://gitcode.com/gh_mirrors/co/convex-backend点击查看免费下载相关推荐编写 Convex 函数从 query 到 mutation 的完整实战指南基于 convex-backend 开源仓库编写 Convex 函数从 query 到 mutation 的完整实战指南基于 convex backend 开源仓库 导读 本文围绕 convex b数据库后端Convex 函数开发实战指南在 Next.js 中编写 Query 与 Mutation基于 convex-backend 源码解析Convex 函数开发实战指南在 Next.js 中编写 Query 与 Mutation基于 convex backend 源码解析 本文以 conve数据库后端Convex 函数开发实战在 TanStack Start WorkOS 示例项目中编写 Query、Mutation 与 ActionConvex 函数开发实战在 TanStack Start WorkOS 示例项目中编写 Query、Mutation 与 Action 本文以开源仓库数据库后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表