Bouw uw eigen API met behulp van deze populaire webtechnologieën.

GraphQL en NestJS vormen een uitstekende samenwerking, waardoor u een solide basis krijgt voor uw API's en een gebruiksvriendelijk raamwerk om schaalbare webapplicaties te bouwen. De combinatie is perfect voor het bouwen van productieklare apps, en beide zijn zeer relevante tools in het huidige technische ecosysteem.

Lees meer over hoe u met beide producten een API kunt bouwen.

Wat is GraphQL?

GraphQL is een taal voor het opvragen en manipuleren van gegevens u kunt gebruiken om API's op een meer precieze en beknopte manier te bouwen. GraphQL biedt een volledige en adequate beschrijving van de gegevens die in een API aanwezig zijn en geeft de klant de mogelijkheid om de exacte gegevens te verkrijgen die nodig zijn.

GraphQL biedt veel functies die REST API's missen, variërend van nauwkeurige gegevensquery's tot betere tooling voor ontwikkelaars, zoals de grafiql editor. Het stelt u ook in staat om meerdere bronnen op te vragen via een enkel verzoek.

instagram viewer

Wat is NestJS?

NestJS is een progressief Node.js-framework dat u kunt gebruiken om schaalbare en efficiënte server-side applicaties te bouwen. NestJS biedt veel plug-ins, naast tooling voor snelle en gemakkelijke ontwikkeling, waaronder GraphQL-ondersteuning, GRPC, WebSockets, enz.

NestJS staat in het ecosysteem bekend om zijn geoptimaliseerde projectstructuur met behulp van modules, controllers, services en schema's. Dankzij de ingebouwde CLI kunt u een gestructureerde API-architectuur creëren. Je kunt gebruiken principes van afhankelijkheidsinjectie om te bepalen hoe de onderdelen van een applicatie met elkaar communiceren.

GraphQL implementeren met NestJS en MongoDB

Voordat u een API bouwt met NestJS en GraphQL, moet u de juiste afhankelijkheden beschikbaar hebben. Jij hebt nodig om Node.js te installeren en NestJS, die u kunt installeren door te draaien npm i -g @nestjs/cli.

Het volgende voorbeeld is een eenvoudige app die informatie over boeken opslaat. Voer de volgende opdracht uit in uw terminal om een ​​nieuwe NestJS-toepassing te maken:

nest nieuw 

Navigeer naar de map van de gegenereerde applicatie () en installeer de afhankelijkheden met de volgende opdracht:

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

Er zijn twee belangrijke benaderingen voor het bouwen van GraphQL API's, namelijk:

  1. Schema-eerste benadering: waar u de API beschrijft in schemadefinitiebestanden of SDL, en NestJS genereert op basis daarvan Typescript-definities.
  2. Code-eerste benadering: waar u query's, mutaties en andere GraphQL-functionaliteiten definieert met behulp van Typescript-klassen en decorateurs, en NestJS genereert op basis daarvan SDL-bestanden.

In het volgende voorbeeld wordt beschreven hoe u een code-eerst-benadering gebruikt.

Eerst moet u GraphQL initialiseren in uw App-module En verbind het met een MongoDB-database:

// app.module.ts
importeren { Module } van'@nestjs/common';
importeren { GraphQLModule als NestGraphQLModule } van'@nestjs/graphql';
importeren { ApolloDriver, ApolloDriverConfig } van'@nestjs/apollo';
importeren { meedoen } van'pad';
importeren { Mongoose-module } van'@nestjs/mangoest';
importeren { AppController } van'./app.controller';
importeren { AppService } van'./app.service';
importeren { ConfigModule, ConfigService } van'@nestjs/config';
importeren mongodbConfig van'./config/mongodb.config';

@module({
invoer: [
ConfigModule.forRoot({
laden: [mongodbConfig],
isGlobal: WAAR
}),
NestGraphQLModule.forRootAsync({
chauffeur: ApolloDriver,
injecteren: [ConfigService],
gebruikfabriek: asynchroon (configService: ConfigService) => ({
autoSchemaFile: deelnemen aan (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: WAAR,
sorteerSchema: WAAR,
speelplaats: WAAR,
foutopsporing: configService.get<booleaans>("DEBUGGEN"),
uploadt: vals,
}),
}),
MongooseModule.forRootAsync({
injecteren: [ConfigService],
gebruikfabriek: asynchroon (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
],
controllers: [AppController],
aanbieders: [AppService],
})

exporterenklas App-module {}

Deze module importeert de GraphQLMule van @nestjs/graphql en de Mongoose-module van @nestjs/mangoest wat helpt om verbinding te maken met MongoDB. De autoSchemaFile eigenschap specificeert de locatie van het gegenereerde schemabestand, en de sorteerSchema eigenschap zorgt ervoor dat de velden alfabetisch worden geordend.

Dit is wat uw MongoDB configuratie bestand zou er zo uit moeten zien:

importeren { registreer als } van'@nestjs/config';

/**
 * Mongo-databaseverbindingsconfiguratie
 */
exporterenstandaard registreren als('mongodb', () => {
const {
MONGO_URI
} = proces.env;

opbrengst {
uri: `${MONGO_URI}`,
};
});

Het GraphQL-schema definiëren

Nadat u de GraphQL- en MongoDB-verbindingen hebt ingesteld, moet u GraphQL-query's en -mutaties definiëren om een ​​schema te genereren (schema.gql) bestand.

Vragen schrijven

In de code-eerste benadering, maak je een model met behulp van de Object type decorateur. Dit model transformeer je later in een GraphQL-type.

Bijvoorbeeld:

// boek.model.ts
importeren { Veld, Objecttype } van'@nestjs/graphql';
importeren { Prop, Schema, SchemaFactory } van'@nestjs/mangoest';
importeren { Document } van'mangoest';

exporterentype BookDocument = Boek & Document;

@Object type()
@Schema()
exporterenklas Boek {
@Veld()
titel: snaar;

@Veld()
auteur: snaar;

@Veld()
datum van het uitbrengen: booleaans;
}

exporterenconst BookSchema = SchemaFactory.createForClass (Boek);

GraphQL kan standaard de gemaakte schema's niet gebruiken. Om ze functioneel te maken, hebt u een resolverservice nodig die de functies bevat voor het uitvoeren van de GraphQL-typen. Dat kan met de Oplosser decorateur.

// boeken.resolver.ts
importeren { Resolver, Query, Mutatie, Args, ID } van'@nestjs/graphql';
importeren { Boek } van'./boek.model';
importeren { BoekenService } van'./boeken.service';

@Oplosser(() => Boek)
exporterenklas BookResolver {
constructeur(privaat alleen-lezen bookService: BookService) { }

@Vraag(() => [Boek])
asynchroon boeken(): Belofte {
opbrengstdit.bookService.findAll();
}

@Vraag(() => Boek)
asynchroon boek(@Args('ID kaart', { type: () => Ik deed: snaar): Belofte {
opbrengstdit.bookService.findOne (id);
}
}

Je kunt de BoekService,hierboven geïmporteerd, als volgt:

// boeken.service.ts
importeren { Injecteerbaar } van'@nestjs/common';
importeren { Injecteer Model } van'@nestjs/mangoest';
importeren { Model } van'mangoest';
importeren { Boek, BoekDocument } van'./boek.model';

@Injecteerbaar()
exporterenklas BoekService {
constructeur(@InjectModel(Boek.naam) privaat boekModel: Model) { }

asynchroon vind alle(): Belofte {
opbrengstdit.bookModel.find().exec();
}

asynchroon vindEen (id: snaar): Belofte {
opbrengstdit.bookModel.findById (id).exec();
}
}

U moet ook de BookResolver toevoegen aan de lijst met providers in boeken.module.ts.

importeren { Module } van"@nestjs/common";
importeren { Mongoose-module } van"@nestjs/mangoest";
importeren { BoekenService } van'./boeken.service';
importeren { BoekOplosser } van'./books.resolver';
importeren { Boek, BoekSchema } van'./boek.model';

@module({
aanbieders: [
Boekenservice,
BoekOplosser
],
invoer: [MongooseModule.forFeature([
{
naam: Boek.naam,
schema: BoekSchema,
},
]),
],
})

exporterenklas BoekenModule {}

Werken met mutaties

Terwijl u een query gebruikt om gegevens in GraphQL op te halen, creëren of updaten mutaties gegevens in de database. Om mutaties aan te maken, moet u gegevens van gebruikers accepteren. De Invoertype decorateur, die een klasse verandert in een GraphQL-invoertype, komt hier van pas.

// boek.input.ts
importeren { Invoertype, Veld } van'@nestjs/graphql';

@InputType()
exporterenklas Boekinvoer {
@Veld()
titel: snaar;

@Veld()
auteur: snaar;

@Veld()
datum van het uitbrengen: booleaans
}

U kunt nu updaten boeken.resolver.ts om er zo uit te zien:

importeren { Resolver, Query, Mutatie, Args, ID } van'@nestjs/graphql';
importeren { Boek } van'./boek.model';
importeren { BoekenService } van'./boeken.service';
importeren { Boekinvoer } van'./boek.invoer';

@Oplosser(() => Boek)
exporterenklas BookResolver {
constructeur(privaat alleen-lezen bookService: BookService) { }

@Mutatie(() => Boek)
asynchroon maakBoek(@Args('invoer') invoer: Boekinvoer): Belofte {
opbrengstdit.bookService.create (invoer);
}

@Mutatie(() => Boek)
asynchroon updateBoek(
@Args('ID kaart', { type: () => Ik deed: snaar,
@Args('invoer') invoer: BookInput,
): Belofte {
opbrengstdit.bookService.update (id, invoer);
}

@Mutatie(() => Boek)
asynchroon verwijderBoek(@Args('ID kaart', { type: () => Ik deed: snaar): Belofte {
opbrengstdit.bookService.delete (id);
}
}

En boeken.service.ts soortgelijk:

importeren { Injecteerbaar } van'@nestjs/common';
importeren { Injecteer Model } van'@nestjs/mangoest';
importeren { Model } van'mangoest';
importeren { Boek, BoekDocument } van'./boek.model';

@Injecteerbaar()
exporterenklas BoekService {
constructeur(@InjectModel(Boek.naam) privaat boekModel: Model) { }

asynchroon creëren (boek: Boek): Belofte {
const nieuwBoek = nieuwdit.bookModel (boek);
opbrengst newBook.save();
}

asynchroon updaten (id: snaar, boek boek): Belofte {
opbrengstdit.bookModel.findByIdAndUpdate (id, boek, { nieuw: WAAR }).exec();
}

asynchroonverwijderen(ID kaart: snaar): Belofte {
opbrengstdit.bookModel.findByIdAndDelete (id).exec();
}
}

De @Mutatie decorateur markeert een functie als een mutatietype en de @Args decorateur pakt alle invoer die in de functie is ingevoerd.

Ten slotte moet u de BoekenModule naar binnen App-module om het functioneel te maken. Je moet ook langs de BoekenModule naar voorRootAsync zoals hieronder te zien is.

importeren { BoekenModule } van'./boeken/boeken.module';
/**
 * overige invoer
*/

@module({
invoer: [
ConfigModule.forRoot({
laden: [mongodbConfig],
isGlobal: WAAR
}),
NestGraphQLModule.forRootAsync({
chauffeur: ApolloDriver,
injecteren: [ConfigService],
gebruikfabriek: asynchroon (configService: ConfigService) => ({
autoSchemaFile: deelnemen aan (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: WAAR,
sorteerSchema: WAAR,
speelplaats: WAAR,
foutopsporing: configService.get<booleaans>("DEBUGGEN"),
uploadt: vals,
}),
}),
MongooseModule.forRootAsync({
injecteren: [ConfigService],
gebruikfabriek: asynchroon (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
BoekenModule,
],
controllers: [AppController],
aanbieders: [AppService],
})

exporterenklas App-module {}

U kunt de code testen door deze uit te voeren npm run start: dev in uw terminal en uw toepassing zou met succes moeten starten op de poort 3000.

Open localhost: 3000/graphql in uw browser om de Graphiql interface waar u query's en mutaties kunt testen. Hier is een voorbeeld dat een query laat zien:

En hier is een voorbeeld van een mutatie:

Bouw efficiënte API's met NestJS en GraphQL

Het bouwen van een GraphQL API in NestJS met MongoDB met behulp van Mongoose omvat het definiëren van een schema voor de GraphQL API, een schema voor het Mongoose-model een service om met de database te communiceren en een resolver om GraphQL-bewerkingen aan de service toe te wijzen methoden.

NestJS heeft ingebouwde functionaliteit voor het bouwen van API's, waaronder decorateurs voor het definiëren van routes, bewakers om ze te beschermen en middlewares voor het afhandelen van verzoeken en antwoorden. Het ondersteunt ook andere databases zoals PostgreSQL, MySQL en SQLite, evenals andere GraphQL-bibliotheken zoals Apollo en TypeGraphQL.