Aller au contenu

Générer des types GraphQL TypeScript pour MongoDB — Numio

Génère des types TypeScript de documents MongoDB à partir d'un schéma annoté avec @entity, @id, @column, @link, @embedded et @map, avec @graphql-codegen/typescript-mongodb. Chaque type @entity reçoit un type <Name>DbObject ; les champs sans directive sont exclus.

Garder typée la forme du document stocké dans MongoDB à côté des types de l'API GraphQL de la même entité.

GraphQL Schema

TypeScript MongoDB

Quand l’utiliser

  • Garder typée la forme du document stocké dans MongoDB à côté des types de l'API GraphQL de la même entité.
  • Voir comment les chemins @map et les références @link se traduisent en objets imbriqués et en tableaux d'ObjectId avant d'écrire le code d'accès aux données.

Mode d’emploi

  1. Collez un schéma dont les types utilisent @entity et dont les champs utilisent @id, @column, @link, @embedded ou @map(path: ...).
  2. Repérez les types DbObject vers la fin de la sortie ; les types GraphQL eux-mêmes sont générés au-dessus.
  3. Copiez le résultat dans un fichier .ts ; il importe ObjectId depuis le package mongodb.

Schéma GraphQL avec directives MongoDB

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
}

Types DbObject TypeScript

…
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
}

Détails et limites

@id devient _id: ObjectId, @link devient le _id de l'entité liée (Array<PostDbObject["_id"]> pour les listes) et @map(path: "login.email") crée un objet login imbriqué.

Les champs sans directive (ni @column, ni @id, ni @link, ni @embedded) ne figurent pas dans le type DbObject ; les colonnes nullable deviennent des propriétés Maybe<T> facultatives.

La sortie contient aussi les types standard du plugin typescript (omis ci-dessus). La génération s'exécute dans un Web Worker de votre navigateur.

FAQ

Dois-je déclarer les directives @entity et @column dans mon schéma ?

Non. Le plugin ajoute ses propres définitions de directives, ce qui explique aussi la présence d'un type input AdditionalEntityFields dans la sortie.

Comment les documents embarqués sont-ils typés ?

Un type déclaré avec @entity(embedded: true) reçoit un type DbObject sans _id, et un champ marqué @embedded y fait référence, par exemple profile: ProfileDbObject.

Pourquoi un champ manque-t-il dans le type DbObject ?

Seuls les champs avec @id, @column, @link, @embedded ou @map sont des champs stockés. Ajoutez @column pour inclure un champ simple.

Spécifications et références