Zum Inhalt springen

TypeScript-Typen für GraphQL und MongoDB generieren — Numio

Erzeugt mit @graphql-codegen/typescript-mongodb TypeScript-Typen für MongoDB-Dokumente aus einem Schema, das mit @entity, @id, @column, @link, @embedded und @map annotiert ist. Jeder @entity-Typ erhält einen Typ <Name>DbObject; Felder ohne Direktive werden weggelassen.

Die Struktur gespeicherter MongoDB-Dokumente typisiert neben den GraphQL-API-Typen derselben Entity pflegen.

GraphQL Schema

TypeScript MongoDB

Wann sie hilft

  • Die Struktur gespeicherter MongoDB-Dokumente typisiert neben den GraphQL-API-Typen derselben Entity pflegen.
  • Sehen, wie @map-Pfade und @link-Referenzen zu verschachtelten Objekten und ObjectId-Arrays werden, bevor du Datenzugriffscode schreibst.

Anwendung

  1. Füge ein Schema ein, dessen Typen @entity und dessen Felder @id, @column, @link, @embedded oder @map(path: ...) verwenden.
  2. Lies die DbObject-Typen gegen Ende der Ausgabe; die GraphQL-Typen selbst werden darüber erzeugt.
  3. Kopiere das Ergebnis in eine .ts-Datei; sie importiert ObjectId aus dem Paket mongodb.

GraphQL-Schema mit MongoDB-Direktiven

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-Typen

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

Details und Einschränkungen

@id wird zu _id: ObjectId, @link zur _id der verknüpften Entity (Array<PostDbObject["_id"]> bei Listen), und @map(path: "login.email") erzeugt ein verschachteltes login-Objekt.

Felder ohne Direktive (kein @column, @id, @link, @embedded) sind nicht im DbObject-Typ enthalten; nullable Spalten werden zu optionalen Maybe<T>-Eigenschaften.

Die Ausgabe enthält außerdem die üblichen Typen des typescript-Plugins (oben ausgelassen). Die Erzeugung läuft in einem Web Worker im Browser.

FAQ

Muss ich die Direktiven @entity und @column in meinem Schema deklarieren?

Nein. Das Plugin fügt eigene Direktivendefinitionen hinzu, weshalb auch ein Input-Typ AdditionalEntityFields in der Ausgabe erscheint.

Wie werden eingebettete Dokumente typisiert?

Ein mit @entity(embedded: true) deklarierter Typ erhält einen DbObject-Typ ohne _id, und ein mit @embedded markiertes Feld verweist darauf, zum Beispiel profile: ProfileDbObject.

Warum fehlt ein Feld im DbObject-Typ?

Nur Felder mit @id, @column, @link, @embedded oder @map sind gespeicherte Felder. Ergänze @column, um ein einfaches Feld aufzunehmen.

Spezifikationen und Referenzen