拓冰建站拓冰建站
首页 / 资讯中心 / 正文

InsForge Database SDK 实战指南:PostgREST 查询构建器、CRUD 与高级过滤

InsForge Database SDK 实战指南PostgREST 查询构建器、CRUD 与高级过滤【免费下载链接】InsForgeThe all-in-one, open-source backend platform for agentic coding. InsForge gives your coding agent database, auth, storage, compute, hosting, and AI gateway to ship full-stack apps end-to-end.项目地址: https://gitcode.com/GitHub_Trending/in/InsForge导读InsForge 是一个开源的全栈后端平台为 AI Agent 提供数据库、认证、存储、计算与托管能力。其中数据库层基于 PostgREST 构建本文档insforge-db-sdk.md沉淀了 InsForge Database SDK 的完整用法从客户端初始化、查询构建器的链式 CRUD到过滤、排序、分页、外键展开与执行语义。读完本文你将掌握在 Agent 编码场景中直接操作 InsForge 数据表的标准姿势并能结合后端源码理解每条链式调用的真实行为与底层原理。快速开始初始化客户端SDK 采用工厂函数createClient创建实例与后端服务默认端口7130建立连接import { createClient } from insforge/sdk; const client createClient({ baseUrl: http://localhost:7130 });初始化完成后所有数据表操作都从client.database入口开始。client.database.from(table)会返回一个可链式调用的QueryBuilder对象任何 CRUD 方法、过滤器与修饰符都可以继续拼接client.database.from(posts) // Returns QueryBuilder从 QueryBuilder 到 PostgREST 代理一次调用的完整旅程SDK 的链式 API 最终会被序列化为 HTTP 请求发送到后端后端并不直接读写数据库而是把请求原样代理给 PostgREST。这条链路在源码中有清晰的落点入口路由records.routes.ts 中router.all(/:tableName, verifyUser, forwardToPostgrest)与router.all(/:tableName/*path, ...)捕获对任意表的任意方法请求先做表名校验validations.ts 的validateTableName再交给代理服务代理核心postgrest-proxy.service.ts 中forwardRequest将请求转发到配置的postgrestBaseUrl并内置最多 3 次重试与指数退避200ms * 2.5^(n-1)上限 1000ms身份转换token.manager.ts 提供三种代理凭证——forwardAsAdminproject_admin角色、永不过期、forwardAsUser5 分钟短效 HS256 token携带用户sub/email/role声明、forwardAsAnon无 subject 的anontoken。也就是说SDK 里写的.select()、.eq()等语法本质上是对 PostgREST 查询字符串的封装而 InsForge 在其中充当了鉴权、限流与安全代理的角色。records-auth.test.tsbackend/tests/unit/records-auth.test.ts与postgrest-proxy-retry.test.tsbackend/tests/unit/postgrest-proxy-retry.test.ts分别覆盖了这两层行为的边界条件。CRUD 操作详解select列选择与查询返回.select() // All columns .select(id, title) // Specific columns .select(*, user:user_id(name, email)) // Foreign key expansionselect()不传参数时返回全部列传入逗号分隔的列名则只返回指定列*通配符结合别名:外键列(嵌套字段)语法可做外键展开详见下文外键展开小节。insert写入并返回数据.insert({ title: Hello }).select() // Single record with data returned .insert([{...}, {...}]).select() // Multiple records with data returned // Note: Always sends array to API // Without .select(), returns null data注意无论传入单个对象还是数组SDK 在请求 PostgREST 时总是以数组格式[{...}]发送 POST 请求体这是 PostgREST 的硬性要求。.select()决定响应体是否携带写入后的完整记录——如果不链式.select()data会是null。update 与 delete必须搭配过滤条件.update({ title: Updated }).eq(id, 123).select() .delete().eq(id, 123).select() // Must chain with filter and .select() to return data更新与删除必须链式调用过滤器如.eq()来限定目标行否则会影响整张表——这既是 PostgREST 的安全语义也符合 InsForge 的服务端约束。同样地链式.select()才能拿到受影响行的返回数据。upsert存在即更新否则插入.upsert({ id: 123, title: New or Update }).select() // Updates if exists, inserts if not // Use .select() to return dataupsert依据主键判断记录是否存在主键冲突则更新无冲突则插入避免了两步式的先查后写。过滤器FiltersSDK 覆盖了 PostgREST 的绝大多数过滤操作符.eq(col, value) // column value .neq(col, value) // column ! value .gt(col, value) // column value .gte(col, value) // column value .lt(col, value) // column value .lte(col, value) // column value .like(col, %pat%) // LIKE pattern .ilike(col, %pat%) // ILIKE pattern .is(col, null) // IS NULL .in(col, [1,2,3]) // IN array .or(status.eq.active,status.eq.pending) // OR condition .and(price.gte.100,price.lte.500) // Explicit AND .not(deleted, is.true) // NOT condition其中字符串比较like/ilike需要配合 SQL 通配符%使用or/and/not使用 PostgREST 的点分操作符语法column.operator.value多个条件用逗号分隔。OR 条件的组合语义// Simple OR .or(status.eq.active,status.eq.pending) // WHERE status active OR status pending // OR with other filters (implicit AND) .eq(user_id, 123) .or(status.eq.draft,status.eq.published) // WHERE user_id 123 AND (status draft OR status published) // Complex OR with NOT .or(age.lt.18,age.gt.65,not.is_active.is.true) // WHERE age 18 OR age 65 OR NOT is_active三个要点值得强调简单 OR逗号即 OR 连接隐式 AND链式调用的其他过滤器与.or()之间是 AND 关系且or内部条件会被括号包裹保证优先级正确复杂 ORnot.前缀可以在 OR 表达式中直接表达取反例如not.is_active.is.true等价于NOT is_active。修饰符Modifiers排序、分页与计数.order(col) // ASC .order(col, { ascending: false }) // DESC .limit(10) .offset(20) .range(0, 9) // Headers: Range: 0-9 .single() // Return object not array .count(exact) // Include total count.order(col, { ascending: false })实现降序.limit()/.offset()控制返回数量与跳过行数.range(start, end)通过Range: start-end请求头做窗口分页.single()将返回体从数组变为单个对象当结果恰好一行时.count(exact)让响应携带精确总数——后端在 response.ts 的paginatedResponse中同样遵循 PostgREST 风格会设置Content-Range: start-end/total头并在未取完时返回206 Partial Content。执行与结果语义QueryBuilder 的所有方法都是thenable的可以直接await// Methods are thenable const { data, error } await client.database .from(posts) .select() .eq(user_id, 123) .limit(10); // data: array or null // error: { message, statusCode, code } or null执行结果统一解构为{ data, error }二元组data成功时为数组select查询或对象配合.single()无返回数据时为nullerror失败时为{ message, statusCode, code }结构化错误对象成功时为null。从后端视角看这个错误对象对应的是 PostgREST 返回的 JSON 错误体。在 records.routes.ts 中代理层错误会原样透传error.response.status与error.response.data而常规响应通过 successResponse 直接以 JSON 返回data。因此 SDK 侧拿到的statusCode与后端/PostgREST 的实际 HTTP 状态码一致message与code则来自错误体内容。外键展开Foreign Key Expansion外键展开沿用 PostgREST 语法把关联表数据直接内嵌进返回对象// PostgREST syntax .select(*, user:user_id(name, email)) // Response: { id: 123, title: Post, user_id: 456, user: { name: John, email: johnexample.com } }user:user_id(...)的含义是以user_id为外键将关联行取出并命名为user只返回其中name与email两列。原始的外键列user_id依然保留同时新增了嵌套的user对象。多级展开、嵌入子查询等更复杂的写法同样受支持可用于减少往返请求次数。Users 表实践个人资料读写文档特别指出users表存放的是用户资料profile数据而非认证数据——认证由 InsForge 的 Auth 服务负责这里只读写资料字段// Profile data (not auth) await client.database.from(users).select().eq(id, userId).single() await client.database.from(users).update({ nickname, avatar_url }).eq(id, userId).select()典型用法是读取时按id精确匹配并配合.single()拿到单个用户对象更新时只改nickname、avatar_url等资料字段并通过.eq(id, userId)限定到当前用户行。用户身份sub由服务端 JWT 声明承载而不是存放在业务表的某列中。使用要点与注意事项原文档在最后以 Notes 形式总结了五条关键约定这里逐一展开底层就是 PostgRESTSDK 的链式语法最终全部映射为 PostgREST 的查询字符串与请求头因此了解 PostgREST 语义如Range头、Prefer头能帮助你更好地预测 SDK 行为POST 请求体必须是数组格式[{...}]insert无论单条还是批量都会发送数组这是服务端解析的前提所有方法返回 QueryBuilder因此可以无限链式组合过滤器与修饰符直到await触发执行执行返回{ data, error }不要用 try/catch 猜测数据结构统一从这两个字段取结果与错误信息写操作必须带过滤器与.select()update/delete不带条件会波及全表不带.select()则拿不到返回数据。从源码看两条额外安全细节表名校验请求到达 PostgREST 之前后端会通过validateTableName校验表名合法性见 validations.ts非法表名会被拒绝这为代理层增加了一道防注入防线空字符串清洗在 records.routes.ts 中POST/PATCH/PUT 请求体会根据列类型过滤空字符串——非文本类型列的空值会被剔除避免向integer、boolean等列写入非法空串这与records-empty-string-stripping.test.ts测试覆盖的行为一致。小结InsForge Database SDK 以 QueryBuilder 的链式 API 提供了完整的 PostgREST 数据操作能力from指定表、select/insert/update/delete/upsert完成 CRUD、过滤操作符与or/and/not组合复杂条件、order/limit/offset/range/single/count控制结果形态最后统一await得到{ data, error }。配合后端源码可见每一句链式调用都经过 InsForge 的鉴权代理三种角色 token 交换、表名校验与错误透传后才到达 PostgREST这让 SDK 在保持 PostgREST 原生能力的同时获得了平台级的认证与安全兜底——这正是 Agent 编码场景下直接、高效操作数据库的标准姿势。【免费下载链接】InsForgeThe all-in-one, open-source backend platform for agentic coding. InsForge gives your coding agent database, auth, storage, compute, hosting, and AI gateway to ship full-stack apps end-to-end.项目地址: https://gitcode.com/GitHub_Trending/in/InsForge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门