Byg din egen API ved hjælp af disse populære webteknologier.

GraphQL og NestJS udgør et fremragende partnerskab, der giver dig et solidt fundament for dine API'er og en brugervenlig ramme til at bygge skalerbare webapplikationer. Kombinationen er perfekt til at bygge produktionsklare apps, og begge er meget relevante værktøjer i nutidens teknologiske økosystem.

Få mere at vide om, hvordan du kan bygge en API ved hjælp af begge produkter.

Hvad er GraphQL?

GraphQL er et dataforespørgsels- og manipulationssprog du kan bruge til at bygge API'er på en mere præcis og kortfattet måde. GraphQL giver en komplet og fyldestgørende beskrivelse af de data, der findes i en API og giver klienten magt til at få de nøjagtige nødvendige data.

GraphQL giver mange funktioner, som REST API'er mangler, lige fra præcise dataforespørgsler til bedre udviklerværktøjer, som f.eks. grafiql redaktør. Det giver dig også mulighed for at forespørge efter flere ressourcer via en enkelt anmodning.

Hvad er NestJS?

NestJS er en progressiv Node.js-ramme, du kan bruge til at bygge skalerbare og effektive server-side-applikationer. NestJS leverer mange plugins sammen med værktøjer til hurtig og nem udvikling, herunder GraphQL-understøttelse, GRPC, WebSockets osv.

instagram viewer

NestJS er velkendt i økosystemet for sin optimerede projektstruktur ved hjælp af moduler, controllere, tjenester og skemaer. Dens indbyggede CLI giver dig mulighed for at skabe en struktureret API-arkitektur. Du kan bruge afhængighedsindsprøjtningsprincipper at kontrollere, hvordan delene af en applikation kommunikerer med hinanden.

Implementering af GraphQL med NestJS og MongoDB

Før du bygger en API med NestJS og GraphQL, skal du have de rigtige afhængigheder til rådighed. Du mangler for at installere Node.js og NestJS, som du kan installere ved at køre npm i -g @nestjs/cli.

Eksemplet, der følger, er en simpel app, der gemmer information om bøger. Kør følgende kommando i din terminal for at oprette en ny NestJS-applikation:

rede ny 

Naviger til den genererede applikations mappe () og installer dens afhængigheder med følgende kommando:

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

Der er to hovedtilgange til at bygge GraphQL API'er, nemlig:

  1. Skema-første tilgang: hvor du beskriver API'en i skemadefinitionsfiler eller SDL, og NestJS genererer Typescript-definitioner baseret på dem.
  2. Kode-først tilgang: hvor du definerer forespørgsler, mutationer og andre GraphQL-funktioner ved hjælp af Typescript-klasser og dekoratorer, og NestJS genererer SDL-filer baseret på dem.

Følgende eksempel beskriver, hvordan man bruger en kode-først tilgang.

Først skal du initialisere GraphQL i din AppModul og tilslut den til en MongoDB-database:

// app.modul.ts
importere { Modul } fra'@nestjs/common';
importere { GraphQLModule som NestGraphQLModule } fra'@nestjs/graphql';
importere { ApolloDriver, ApolloDriverConfig } fra'@nestjs/apollo';
importere { tilslutte } fra'sti';
importere { MongooseModule } fra'@nestjs/mongoose';
importere { AppController } fra'./app.controller';
importere { AppService } fra'./app.service';
importere { ConfigModule, ConfigService } fra'@nestjs/config';
importere mongodbConfig fra'./config/mongodb.config';

@Modul({
import: [
ConfigModule.forRoot({
indlæs: [mongodbConfig],
isGlobal: rigtigt
}),
NestGraphQLModule.forRootAsync({
chauffør: ApolloDriver,
inject: [ConfigService],
useFactory: asynkron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: rigtigt,
sortSchema: rigtigt,
legeplads: rigtigt,
debug: configService.get<boolesk>("FEJLFINDE"),
uploads: falsk,
}),
}),
MongooseModule.forRootAsync({
inject: [ConfigService],
useFactory: asynkron (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
],
controllere: [AppController],
udbydere: [AppService],
})

eksportklasse AppModule {}

Dette modul importerer GraphQLModule fra @nestjs/graphql og MongooseModul fra @nestjs/mongoose som hjælper med at oprette forbindelse til MongoDB. Det autoSchemaFile egenskaben angiver placeringen af ​​den genererede skemafil, og sortSchema egenskab sikrer, at den ordner felterne alfabetisk.

Her er hvad din MongoDB config filen skal se sådan ud:

importere { registerAs } fra'@nestjs/config';

/**
 * Mongo-databaseforbindelseskonfiguration
 */
eksportStandard registerAs('mongodb', () => {
konst {
MONGO_URI
} = proces.env;

Vend tilbage {
uri: `${MONGO_URI}`,
};
});

Definition af GraphQL-skemaet

Efter at have konfigureret GraphQL- og MongoDB-forbindelserne, bør du definere GraphQL-forespørgsler og mutationer for at generere et skema (schema.gql) fil.

Skrive forespørgsler

I den kode-første tilgang, opretter du en model ved hjælp af Objekttype dekoratør. Du vil senere omdanne denne model til en GraphQL-type.

For eksempel:

// book.model.ts
importere { Field, ObjectType } fra'@nestjs/graphql';
importere { Prop, Schema, SchemaFactory } fra'@nestjs/mongoose';
importere { Dokument } fra'mangust';

eksporttype BookDocument = Bog & Dokument;

@ObjectType()
@Skema()
eksportklasse Bestil {
@Mark()
titel: snor;

@Mark()
forfatter: snor;

@Mark()
publiceringsdato: boolesk;
}

eksportkonst BookSchema = SchemaFactory.createForClass (Bog);

GraphQL kan som standard ikke bruge de oprettede skemaer. For at gøre dem funktionelle har du brug for en resolver-tjeneste, der indeholder funktionerne til at udføre GraphQL-typerne. Det kan du gøre med Opløser dekoratør.

// books.resolver.ts
importere { Resolver, Query, Mutation, Args, ID } fra'@nestjs/graphql';
importere { Bestil } fra'./bog.model';
importere { Bogservice } fra'./books.service';

@Resolver(() => Bestil)
eksportklasse BookResolver {
konstruktør(privat readonly bookService: BookService) { }

@Forespørgsel(() => [Bestil])
asynkron bøger(): Løfte {
Vend tilbagedet her.bookService.findAll();
}

@Forespørgsel(() => Bestil)
asynkron Bestil(@Args('id', { type: () => Jeg gjorde: snor): Løfte {
Vend tilbagedet her.bookService.findOne (id);
}
}

Du kan implementere Bogservice,importeret ovenfor, som følger:

// books.service.ts
importere { Injicerbar } fra'@nestjs/common';
importere { InjectModel } fra'@nestjs/mongoose';
importere { Model } fra'mangust';
importere { Bog, Bogdokument } fra'./bog.model';

@Injicerbar()
eksportklasse Bogservice {
konstruktør(@InjectModel(Bog.navn) privat bogModel: Model) { }

asynkron findAll(): Løfte {
Vend tilbagedet her.bookModel.find().exec();
}

asynkron findOne (id: snor): Løfte {
Vend tilbagedet her.bookModel.findById (id).exec();
}
}

Du skal også tilføje BookResolver til listen over udbydere i books.modul.ts.

importere { Modul } fra"@nestjs/common";
importere { MongooseModule } fra"@nestjs/mongoose";
importere { Bogservice } fra'./books.service';
importere { BookResolver } fra'./books.resolver';
importere { Bog, Bogskema } fra'./bog.model';

@Modul({
udbydere: [
Bogservice,
BookResolver
],
importerer: [MongooseModule.forFeature([
{
navn: Bog.navn,
skema: BookSchema,
},
]),
],
})

eksportklasse Bogmodul {}

Arbejde med mutationer

Mens du bruger en forespørgsel til at hente data i GraphQL, opretter eller opdaterer mutationer data i databasen. For at oprette mutationer skal du acceptere data fra brugere. Det InputType decorator, som gør en klasse til en GraphQL-inputtype, er praktisk her.

// book.input.ts
importere { InputType, Field } fra'@nestjs/graphql';

@InputType()
eksportklasse BookInput {
@Mark()
titel: snor;

@Mark()
forfatter: snor;

@Mark()
publiceringsdato: boolesk
}

Du kan nu opdatere books.resolver.ts at se sådan ud:

importere { Resolver, Query, Mutation, Args, ID } fra'@nestjs/graphql';
importere { Bestil } fra'./bog.model';
importere { Bogservice } fra'./books.service';
importere { BookInput } fra'./bog.input';

@Resolver(() => Bestil)
eksportklasse BookResolver {
konstruktør(privat readonly bookService: BookService) { }

@Mutation(() => Bestil)
asynkron skabebog(@Args('input') input: BookInput): Løfte {
Vend tilbagedet her.bookService.create (input);
}

@Mutation(() => Bestil)
asynkron opdateringsbog(
@Args('id', { type: () => Jeg gjorde: snor,
@Args('input') input: BookInput,
): Løfte {
Vend tilbagedet her.bookService.update (id, input);
}

@Mutation(() => Bestil)
asynkron sletbog(@Args('id', { type: () => Jeg gjorde: snor): Løfte {
Vend tilbagedet her.bookService.delete (id);
}
}

Og books.service.ts sådan her:

importere { Injicerbar } fra'@nestjs/common';
importere { InjectModel } fra'@nestjs/mongoose';
importere { Model } fra'mangust';
importere { Bog, Bogdokument } fra'./bog.model';

@Injicerbar()
eksportklasse Bogservice {
konstruktør(@InjectModel(Bog.navn) privat bogModel: Model) { }

asynkron oprette (bog: Bog): Løfte {
konst nybog = nydet her.bookModel (bog);
Vend tilbage newBook.save();
}

asynkron opdatering (id: snor, bog: Bog): Løfte {
Vend tilbagedet her.bookModel.findByIdAndUpdate (id, bog, { ny: rigtigt }).exec();
}

asynkronslette(id: snor): Løfte {
Vend tilbagedet her.bookModel.findByIdAndDelete (id).exec();
}
}

Det @Mutation dekoratør markerer en funktion som en mutationstype og den @Args decorator griber alle input, der sendes til funktionen.

Endelig skal du importere Bogmodul ind i AppModul at gøre det funktionelt. Du skal også bestå Bogmodul til til RootAsync som det ses nedenfor.

importere { BooksModule } fra'./books/books.module';
/**
 * anden import
*/

@Modul({
import: [
ConfigModule.forRoot({
indlæs: [mongodbConfig],
isGlobal: rigtigt
}),
NestGraphQLModule.forRootAsync({
chauffør: ApolloDriver,
inject: [ConfigService],
useFactory: asynkron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: rigtigt,
sortSchema: rigtigt,
legeplads: rigtigt,
debug: configService.get<boolesk>("FEJLFINDE"),
uploads: falsk,
}),
}),
MongooseModule.forRootAsync({
inject: [ConfigService],
useFactory: asynkron (configService: ConfigService) => ({
uri: configService.get('MONGO_URI')
})
}),
Bogmodul,
],
controllere: [AppController],
udbydere: [AppService],
})

eksportklasse AppModule {}

Du kan teste koden ved at køre npm run start: dev i din terminal, og din applikation skulle starte med succes på port 3000.

Åben localhost: 3000/graphql i din browser for at vise Graphiql grænseflade, hvor du kan teste forespørgsler og mutationer. Her er et eksempel, der viser en forespørgsel:

Og her er et eksempel på en mutation:

Byg effektive API'er med NestJS og GraphQL

Opbygning af en GraphQL API i NestJS med MongoDB ved hjælp af Mongoose involverer at definere et skema for GraphQL API, et skema for Mongoose-modellen, en service til at interagere med databasen og en resolver til at kortlægge GraphQL-operationer til service metoder.

NestJS har indbygget funktionalitet til at bygge API'er, herunder dekoratorer til at definere ruter, vagter til at beskytte dem og middleware til håndtering af anmodninger og svar. Det understøtter også andre databaser som PostgreSQL, MySQL og SQLite, såvel som andre GraphQL-biblioteker som Apollo og TypeGraphQL.