数据驱动:生成MongoDB用TypeScript GraphQL — Numio
使用 @graphql-codegen/typescript-mongodb,根据带有 @entity、@id、@column、@link、@embedded 和 @map 注解的 schema 生成 TypeScript MongoDB 文档类型。每个 @entity 类型都会得到一个 <Name>DbObject 类型;没有指令的字段不会包含在内。
让同一实体在 MongoDB 中存储的文档结构与 GraphQL API 类型一起保持类型化。
适用场景
- 让同一实体在 MongoDB 中存储的文档结构与 GraphQL API 类型一起保持类型化。
- 在编写数据访问代码之前,查看 @map 路径和 @link 引用会转换成怎样的嵌套对象和 ObjectId 数组。
使用方法
- 粘贴一个类型使用 @entity、字段使用 @id、@column、@link、@embedded 或 @map(path: ...) 的 schema。
- 在输出末尾附近查看 DbObject 类型;GraphQL 类型本身生成在它们上方。
- 将结果复制到 .ts 文件中;它会从 mongodb 包导入 ObjectId。
带 MongoDB 指令的 GraphQL schema
type User @entity {
id: ID! @id
email: String! @column @map(path: "login.email")
profile: Profile! @embedded
posts: [Post!]! @link
}
type Profile @entity(embedded: true) {
name: String! @column
}
type Post @entity {
id: ID! @id
title: String! @column
}TypeScript DbObject 类型
…
export type AdditionalEntityFields = {
path?: InputMaybe<Scalars["String"]["input"]>
type?: InputMaybe<Scalars["String"]["input"]>
}
import { ObjectId } from "mongodb"
export type UserDbObject = {
_id: ObjectId
login: {
email: string
}
profile: ProfileDbObject
posts: Array<PostDbObject["_id"]>
}
export type ProfileDbObject = {
name: string
}
export type PostDbObject = {
_id: ObjectId
title: string
}功能与限制
@id 变为 _id: ObjectId,@link 变为被链接实体的 _id(列表为 Array<PostDbObject["_id"]>),@map(path: "login.email") 会生成嵌套的 login 对象。
没有指令的字段(没有 @column、@id、@link、@embedded)不会包含在 DbObject 类型中;可空的 column 变为可选的 Maybe<T> 属性。
输出中还包含标准 typescript 插件生成的类型(上例中已省略)。生成在浏览器的 Web Worker 中运行。
FAQ
需要在 schema 中声明 @entity 和 @column 指令吗?
不需要。插件会添加自己的指令定义,这也是输出中出现 AdditionalEntityFields input 类型的原因。
嵌入文档如何类型化?
用 @entity(embedded: true) 声明的类型会得到一个不含 _id 的 DbObject 类型,标记了 @embedded 的字段会引用它,例如 profile: ProfileDbObject。
为什么 DbObject 类型中缺少某个字段?
只有带 @id、@column、@link、@embedded 或 @map 的字段才是存储字段。为普通字段加上 @column 即可包含它。