MongoDBのためのTypeScript GraphQLジェネレーター — Numio
@graphql-codegen/typescript-mongodb を使って、@entity、@id、@column、@link、@embedded、@map で注釈したスキーマから TypeScript の MongoDB ドキュメント型を生成します。@entity の型ごとに <Name>DbObject 型ができ、ディレクティブのないフィールドは含まれません。
同じエンティティについて、MongoDB に保存するドキュメントの形を GraphQL API の型と並べて型付きに保つ。
こんなときに使えます
- 同じエンティティについて、MongoDB に保存するドキュメントの形を GraphQL API の型と並べて型付きに保つ。
- データアクセスのコードを書く前に、@map のパスや @link の参照がネストしたオブジェクトや ObjectId の配列にどう変換されるかを確認する。
使い方
- 型に @entity、フィールドに @id、@column、@link、@embedded、@map(path: ...) を使ったスキーマを貼り付けます。
- 出力の末尾近くにある DbObject 型を確認します。GraphQL の型自体はその上に生成されます。
- 結果を .ts ファイルにコピーします。mongodb パッケージから ObjectId をインポートします。
MongoDB ディレクティブ付き GraphQL スキーマ
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 型に含まれません。nullable な column は省略可能な Maybe<T> プロパティになります。
出力には標準の typescript プラグインの型も含まれます(上の例では省略)。生成はブラウザの Web Worker で実行されます。
FAQ
スキーマで @entity や @column ディレクティブを宣言する必要はありますか?
ありません。プラグインが独自のディレクティブ定義を追加します。出力に AdditionalEntityFields という input 型が現れるのもそのためです。
埋め込みドキュメントはどう型付けされますか?
@entity(embedded: true) で宣言した型には _id のない DbObject 型ができ、@embedded を付けたフィールドがそれを参照します。例:profile: ProfileDbObject。
DbObject 型にフィールドがないのはなぜですか?
保存対象のフィールドになるのは @id、@column、@link、@embedded、@map のいずれかを持つものだけです。普通のフィールドを含めるには @column を付けてください。