Erstellen Sie Ihre eigene API mit diesen beliebten Webtechnologien.

GraphQL und NestJS bilden eine hervorragende Partnerschaft, die Ihnen eine solide Grundlage für Ihre APIs und ein benutzerfreundliches Framework zum Erstellen skalierbarer Webanwendungen bietet. Die Kombination ist perfekt für die Erstellung produktionsreifer Apps, und beide sind sehr relevante Tools im heutigen Tech-Ökosystem.

Erfahren Sie mehr darüber, wie Sie mit beiden Produkten eine API erstellen können.

Was ist GraphQL?

GraphQL ist eine Datenabfrage- und Manipulationssprache können Sie verwenden, um APIs präziser und prägnanter zu erstellen. GraphQL bietet eine vollständige und angemessene Beschreibung der in einer API vorhandenen Daten und gibt dem Client die Möglichkeit, genau die benötigten Daten zu erhalten.

GraphQL bietet viele Funktionen, die REST-APIs fehlen, von präzisen Datenabfragen bis hin zu besseren Entwicklertools, wie z grafisch Editor. Es ermöglicht Ihnen auch, mehrere Ressourcen über eine einzige Anfrage abzufragen.

instagram viewer

Was ist NestJS?

NestJS ist ein fortschrittliches Node.js-Framework, mit dem Sie skalierbare und effiziente serverseitige Anwendungen erstellen können. NestJS bietet viele Plugins sowie Tools für eine schnelle und einfache Entwicklung, einschließlich GraphQL-Unterstützung, GRPC, WebSockets usw.

NestJS ist im Ökosystem für seine optimierte Projektstruktur mit Modulen, Controllern, Diensten und Schemas bekannt. Die integrierte CLI ermöglicht es Ihnen, eine strukturierte API-Architektur zu erstellen. Sie können verwenden Abhängigkeitsinjektionsprinzipien um zu steuern, wie die Teile einer Anwendung miteinander kommunizieren.

Implementieren von GraphQL mit NestJS und MongoDB

Bevor Sie eine API mit NestJS und GraphQL erstellen, müssen Sie die richtigen Abhängigkeiten verfügbar haben. Du brauchst um Node.js zu installieren und NestJS, das Sie durch Ausführen installieren können npm i -g @nestjs/cli.

Das folgende Beispiel ist eine einfache App, die Informationen zu Büchern speichert. Führen Sie den folgenden Befehl in Ihrem Terminal aus, um eine neue NestJS-Anwendung zu erstellen:

Nest neu 

Navigieren Sie zum Verzeichnis der generierten Anwendung () und installieren Sie seine Abhängigkeiten mit dem folgenden Befehl:

$ npm install --save @nestjs/config @nestjs/graphql graphql-tools graphql \
 @nestjs/apollo apollo-server-express @nestjs/mongoose @types/graphql

Es gibt zwei Hauptansätze zum Erstellen von GraphQL-APIs, nämlich:

  1. Schema-First-Ansatz: wo Sie die API in Schema-Definitionsdateien oder SDL beschreiben und NestJS TypeScript-Definitionen basierend darauf generiert.
  2. Code-First-Ansatz: Hier definieren Sie Abfragen, Mutationen und andere GraphQL-Funktionalitäten mithilfe von Typescript-Klassen und Dekoratoren, und NestJS generiert darauf basierende SDL-Dateien.

Das folgende Beispiel beschreibt, wie ein Code-First-Ansatz verwendet wird.

Zuerst müssen Sie GraphQL in Ihrem initialisieren AppModul Und Verbinden Sie es mit einer MongoDB-Datenbank:

// app.module.ts
importieren { Modul } aus'@nestjs/common';
importieren { GraphQLModul als NestGraphQLModul } aus'@nestjs/graphql';
importieren { ApolloDriver, ApolloDriverConfig } aus'@nestjs/apollo';
importieren { verbinden } aus'Weg';
importieren { MungoModul } aus'@nestjs/mongoose';
importieren {AppController} aus'./app.controller';
importieren {AppService} aus'./app.service';
importieren { Konfigurationsmodul, Konfigurationsdienst } aus'@nestjs/config';
importieren mongodbConfig aus'./config/mongodb.config';

@Modul({
Importe: [
ConfigModule.forRoot({
laden: [mongodbConfig],
istGlobal: WAHR
}),
NestGraphQLModule.forRootAsync({
Fahrer: ApolloDriver,
inject: [ConfigService],
useFactory: asynchron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: WAHR,
sortSchema: WAHR,
Spielplatz: WAHR,
debuggen: configService.get<boolesch>("DEBUGGEN"),
Uploads: FALSCH,
}),
}),
MongooseModule.forRootAsync({
inject: [ConfigService],
useFactory: asynchron (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
],
Controller: [AppController],
Anbieter: [AppService],
})

ExportKlasse AppModule {}

Dieses Modul importiert die GraphQLModul aus @nestjs/graphql und das MongooseModul aus @nestjs/mongoose was hilft, sich mit MongoDB zu verbinden. Der autoSchemaFile -Eigenschaft gibt den Speicherort der generierten Schemadatei an, und die sortSchema -Eigenschaft stellt sicher, dass die Felder alphabetisch sortiert werden.

Hier ist, was Ihre MongoDB Konfig Datei sollte so aussehen:

importieren { registrierenAls } aus'@nestjs/config';

/**
 * Konfiguration der Mongo-Datenbankverbindung
 */
ExportStandard registrierenAls('mongodb', () => {
konst {
MONGO_URI
} = process.env;

zurückkehren {
uri: `${MONGO_URI}`,
};
});

Definieren des GraphQL-Schemas

Nachdem Sie die GraphQL- und MongoDB-Verbindungen eingerichtet haben, sollten Sie GraphQL-Abfragen und -Mutationen definieren, um ein Schema zu generieren (schema.gql) Datei.

Abfragen schreiben

Im Code-First-Ansatz, erstellen Sie ein Modell mithilfe von Objekttyp Dekorateur. Sie werden dieses Modell später in einen GraphQL-Typ umwandeln.

Zum Beispiel:

// Buch.Modell.ts
importieren { Feld, Objekttyp } aus'@nestjs/graphql';
importieren { Prop, Schema, SchemaFactory } aus'@nestjs/mongoose';
importieren { Dokumentieren } aus'Mungo';

ExportTyp BuchDokument = Buch & Dokument;

@Objekttyp()
@Schema()
ExportKlasse Buch {
@Feld()
Titel: Schnur;

@Feld()
Autor: Schnur;

@Feld()
Veröffentlichungsdatum: boolesch;
}

Exportkonst BookSchema = SchemaFactory.createForClass (Buch);

GraphQL kann die erstellten Schemas standardmäßig nicht verwenden. Um sie funktionsfähig zu machen, benötigen Sie einen Resolver-Dienst, der die Funktionen zum Ausführen der GraphQL-Typen enthält. Sie können dies mit dem tun Resolver Dekorateur.

// books.resolver.ts
importieren { Resolver, Abfrage, Mutation, Argumente, ID } aus'@nestjs/graphql';
importieren { Buch } aus'./Buch.Modell';
importieren { Buchservice } aus'./books.service';

@Resolver(() => Buch)
ExportKlasse BookResolver {
Konstrukteur(Privatgelände schreibgeschützter Buchservice: Buchservice) { }

@Anfrage(() => [Buch])
asynchron Bücher(): Versprechen {
zurückkehrenDas.bookService.findAll();
}

@Anfrage(() => Buch)
asynchron Buch(@Args('Ausweis', { Typ: () => Ich tat: Schnur): Versprechen {
zurückkehrenDas.bookService.findOne (id);
}
}

Sie können die implementieren BuchService, oben importiert, wie folgt:

// bücher.service.ts
importieren {Injizierbar} aus'@nestjs/common';
importieren { InjectModel } aus'@nestjs/mongoose';
importieren { Modell } aus'Mungo';
importieren { Buch, BuchDokument } aus'./Buch.Modell';

@ Injizierbar()
ExportKlasse BuchService {
Konstrukteur(@InjectModel(Buch.name) Privatgelände bookModel: Modell) { }

asynchron finde alle(): Versprechen {
zurückkehrenDas.bookModel.find().exec();
}

asynchron findOne (ID: Schnur): Versprechen {
zurückkehrenDas.bookModel.findById (id).exec();
}
}

Sie müssen den BookResolver auch zur Liste der Anbieter in hinzufügen books.module.ts.

importieren { Modul } aus"@nestjs/common";
importieren { MungoModul } aus"@nestjs/mongoose";
importieren { Buchservice } aus'./books.service';
importieren { BookResolver } aus'./books.resolver';
importieren { Buch, Buchschema } aus'./Buch.Modell';

@Modul({
Anbieter: [
BuchService,
BookResolver
],
importiert: [MongooseModule.forFeature([
{
Name: Buch.Name,
Schema: BookSchema,
},
]),
],
})

ExportKlasse BücherModul {}

Arbeiten mit Mutationen

Während Sie eine Abfrage verwenden, um Daten in GraphQL abzurufen, erstellen oder aktualisieren Mutationen Daten in der Datenbank. Um Mutationen zu erstellen, müssen Sie Daten von Benutzern akzeptieren. Der Eingabetyp decorator, der eine Klasse in einen GraphQL-Eingabetyp umwandelt, ist hier praktisch.

// book.input.ts
importieren { Eingabetyp, Feld } aus'@nestjs/graphql';

@Eingabetyp()
ExportKlasse BuchEingabe {
@Feld()
Titel: Schnur;

@Feld()
Autor: Schnur;

@Feld()
Veröffentlichungsdatum: boolesch
}

Sie können jetzt aktualisieren books.resolver.ts so aussehen:

importieren { Resolver, Abfrage, Mutation, Argumente, ID } aus'@nestjs/graphql';
importieren { Buch } aus'./Buch.Modell';
importieren { Buchservice } aus'./books.service';
importieren { Bucheingabe } aus'./book.input';

@Resolver(() => Buch)
ExportKlasse BookResolver {
Konstrukteur(Privatgelände schreibgeschützter Buchservice: Buchservice) { }

@Mutation(() => Buch)
asynchron createBook(@Args('Eingang') Eingabe: BookInput): Versprechen {
zurückkehrenDas.bookService.create (Eingabe);
}

@Mutation(() => Buch)
asynchron updateBook(
@Args('Ausweis', { Typ: () => Ich tat: Schnur,
@Args('Eingang') Eingabe: BookInput,
): Versprechen {
zurückkehrenDas.bookService.update (ID, Eingabe);
}

@Mutation(() => Buch)
asynchron deleteBook(@Args('Ausweis', { Typ: () => Ich tat: Schnur): Versprechen {
zurückkehrenDas.bookService.delete (ID);
}
}

Und bücher.service.ts so was:

importieren {Injizierbar} aus'@nestjs/common';
importieren { InjectModel } aus'@nestjs/mongoose';
importieren { Modell } aus'Mungo';
importieren { Buch, BuchDokument } aus'./Buch.Modell';

@ Injizierbar()
ExportKlasse BuchService {
Konstrukteur(@InjectModel(Buch.name) Privatgelände bookModel: Modell) { }

asynchron erstellen (Buch: Buch): Versprechen {
konst neuesBuch = neuDas.bookModel (Buch);
zurückkehren newBook.save();
}

asynchron aktualisieren (ID: Schnur, Buch Buch): Versprechen {
zurückkehrenDas.bookModel.findByIdAndUpdate (ID, Buch, { neu: WAHR }).exec();
}

asynchronlöschen(Ausweis: Schnur): Versprechen {
zurückkehrenDas.bookModel.findByIdAndDelete (id).exec();
}
}

Der @Mutation decorator markiert eine Funktion als Mutationstyp und die @Args decorator schnappt sich alle Eingaben, die an die Funktion übergeben werden.

Schließlich sollten Sie die importieren BücherModul hinein AppModul um es funktionstüchtig zu machen. Sie sollten auch die bestehen BücherModul Zu forRootAsync wie unten zu sehen.

importieren { BücherModul } aus'./books/books.module';
/**
 * andere Importe
*/

@Modul({
Importe: [
ConfigModule.forRoot({
laden: [mongodbConfig],
istGlobal: WAHR
}),
NestGraphQLModule.forRootAsync({
Fahrer: ApolloDriver,
inject: [ConfigService],
useFactory: asynchron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: WAHR,
sortSchema: WAHR,
Spielplatz: WAHR,
debuggen: configService.get<boolesch>("DEBUGGEN"),
Uploads: FALSCH,
}),
}),
MongooseModule.forRootAsync({
inject: [ConfigService],
useFactory: asynchron (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
BücherModul,
],
Controller: [AppController],
Anbieter: [AppService],
})

ExportKlasse AppModule {}

Sie können den Code testen, indem Sie ihn ausführen npm-Start ausführen: dev in Ihrem Terminal, und Ihre Anwendung sollte erfolgreich am Port starten 3000.

Offen localhost: 3000/graphql in Ihrem Browser, um die anzuzeigen Grafik Schnittstelle, auf der Sie Abfragen und Mutationen testen können. Hier ist ein Beispiel, das eine Abfrage zeigt:

Und hier ist ein Beispiel für eine Mutation:

Erstellen Sie effiziente APIs mit NestJS und GraphQL

Das Erstellen einer GraphQL-API in NestJS mit MongoDB unter Verwendung von Mongoose umfasst das Definieren eines Schemas für die GraphQL-API, ein Schema für das Mongoose-Modell einen Dienst zur Interaktion mit der Datenbank und einen Resolver zur Zuordnung von GraphQL-Operationen zum Dienst Methoden.

NestJS verfügt über integrierte Funktionen zum Erstellen von APIs, einschließlich Decorators zum Definieren von Routen, Guards zu deren Schutz und Middlewares zum Verarbeiten von Anfragen und Antworten. Es unterstützt auch andere Datenbanken wie PostgreSQL, MySQL und SQLite sowie andere GraphQL-Bibliotheken wie Apollo und TypeGraphQL.