Creați-vă propriul API folosind aceste tehnologii web populare.
GraphQL și NestJS formează un parteneriat excelent, oferindu-vă o bază solidă pentru API-urile dvs. și un cadru ușor de utilizat pentru a construi aplicații web scalabile. Combinația este perfectă pentru construirea de aplicații pregătite pentru producție și ambele sunt instrumente foarte relevante în ecosistemul tehnologic de astăzi.
Aflați mai multe despre cum puteți crea un API folosind ambele produse.
Ce este GraphQL?
GraphQL este un limbaj de interogare și manipulare a datelor puteți utiliza pentru a construi API-uri într-un mod mai precis și mai concis. GraphQL oferă o descriere completă și adecvată a datelor existente într-un API și oferă clientului puterea de a obține datele exacte necesare.
GraphQL oferă multe caracteristici care le lipsesc API-urilor REST, de la interogări precise de date la instrumente mai bune pentru dezvoltatori, cum ar fi graphiql editor. De asemenea, vă permite să căutați mai multe resurse printr-o singură solicitare.
Ce este NestJS?
NestJS este un cadru progresiv Node.js pe care îl puteți folosi pentru a construi aplicații scalabile și eficiente pe partea de server. NestJS oferă multe plugin-uri, alături de instrumente pentru dezvoltare rapidă și ușoară, inclusiv suport GraphQL, GRPC, WebSockets etc.
NestJS este binecunoscut în ecosistem pentru structura sa optimizată de proiect, folosind module, controlere, servicii și scheme. CLI-ul său încorporat vă permite să creați o arhitectură API structurată. Poți să folosești principiile injectării dependenței pentru a controla modul în care părțile unei aplicații comunică între ele.
Implementarea GraphQL cu NestJS și MongoDB
Înainte de a construi un API cu NestJS și GraphQL, va trebui să aveți la dispoziție dependențele potrivite. Ai nevoie pentru a instala Node.js și NestJS, pe care îl puteți instala rulând npm i -g @nestjs/cli.
Exemplul care urmează este o aplicație simplă care stochează informații despre cărți. Rulați următoarea comandă în terminal pentru a crea o nouă aplicație NestJS:
cuib nou
Navigați la directorul aplicației generate () și instalați dependențele sale cu următoarea comandă:
$ npm install --save @nestjs/config @nestjs/graphql graphql-tools graphql \
@nestjs/apollo apollo-server-express @nestjs/mongoose @types/graphql
Există două abordări majore pentru construirea API-urilor GraphQL, și anume:
- Prima abordare schematică: unde descrieți API-ul în fișierele de definire a schemei sau SDL, iar NestJS generează definiții Typescript pe baza acestora.
- Abordare prin cod: unde definiți interogări, mutații și alte funcționalități GraphQL folosind clase și decoratori Typescript, iar NestJS generează fișiere SDL pe baza acestora.
Următorul exemplu descrie cum să utilizați o abordare bazată pe cod.
În primul rând, trebuie să inițializați GraphQL în dvs AppModule și conectați-l la o bază de date MongoDB:
// app.module.ts
import { Modulul } din„@nestjs/common”;
import { GraphQLModule la fel de NestGraphQLModule } din„@nestjs/graphql”;
import { ApolloDriver, ApolloDriverConfig } din„@nestjs/apollo”;
import { a te alatura } din'cale';
import { MongooseModule } din„@nestjs/mongoose”;
import { AppController } din„./app.controller”;
import { AppService } din„./app.service”;
import { ConfigModule, ConfigService } din„@nestjs/config”;
import mongodbConfig din„./config/mongodb.config”;@Modul({
importuri: [
ConfigModule.forRoot({
încărcare: [mongodbConfig],
isGlobal: Adevărat
}),
NestGraphQLModule.forRootAsync({
șofer: ApolloDriver,
injectați: [ConfigService],
useFactory: asincron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), „src/schema.gql”),
install SubscriptionHandlers: Adevărat,
sortSchema: Adevărat,
loc de joaca: Adevărat,
depanare: configService.get<boolean>(„DEBUG”),
încărcări: fals,
}),
}),
MongooseModule.forRootAsync({
injectați: [ConfigService],
useFactory: asincron (configService: ConfigService) => ({
uri: configService.get(„MONGO_URI”)
})
}),
],
controlere: [AppController],
furnizori: [AppService],
})
exportclasă AppModule {}
Acest modul importă fișierul GraphQLModule din @nestjs/graphql si MangooseModule din @nestjs/mongoose care ajută la conectarea la MongoDB. The autoSchemaFile proprietatea specifică locația fișierului de schemă generat și sortSchema proprietatea asigură că ordonează câmpurile în ordine alfabetică.
Iată ce este MongoDB config fișierul ar trebui să arate așa:
import { registerAs } din„@nestjs/config”;
/**
* Configurarea conexiunii bazei de date Mongo
*/
exportMod implicit registerAs(„mongodb”, () => {
const {
MONGO_URI
} = process.env;
întoarcere {
uri: `${MONGO_URI}`,
};
});
Definirea schemei GraphQL
După ce ați configurat conexiunile GraphQL și MongoDB, ar trebui să definiți interogări și mutații GraphQL pentru a genera o schemă (schema.gql) fișier.
Scrierea întrebărilor
În abordare prin cod, creați un model folosind ObjectType decorator. Mai târziu veți transforma acest model într-un tip GraphQL.
De exemplu:
// carte.model.ts
import { Field, ObjectType } din„@nestjs/graphql”;
import { Prop, Schema, SchemaFactory } din„@nestjs/mongoose”;
import { Document } din'mangustă';exporttip BookDocument = Carte și document;
@ObjectType()
@Schemă()
exportclasă Carte {
@Camp()
titlu: şir;@Camp()
autor: şir;@Camp()
date publicate: boolean;
}
exportconst BookSchema = SchemaFactory.createForClass (Carte);
GraphQL, în mod implicit, nu poate folosi schemele create. Pentru a le face funcționale, aveți nevoie de un serviciu de rezolvare care conține funcțiile pentru executarea tipurilor GraphQL. Puteți face acest lucru cu Rezolvator decorator.
// cărți.resolver.ts
import { Resolver, Query, Mutation, Args, ID } din„@nestjs/graphql”;
import { Carte } din„./carte.model”;
import { BookService } din„./books.service”;@Resolver(() => Carte)
exportclasă BookResolver {
constructor(privat readonly bookService: BookService) { }@Interogare(() => [Carte])
asincron carti(): Promisiune{
întoarcereacest.bookService.findAll();
}
@Interogare(() => Carte)
asincron carte(@Args('id', { tip: () => Am facut: şir): Promisiune{
întoarcereacest.bookService.findOne (id);
}
}
Puteți implementa BookService,importat mai sus, după cum urmează:
// books.service.ts
import { injectabil } din„@nestjs/common”;
import { InjectModel } din„@nestjs/mongoose”;
import { Model } din'mangustă';
import { Carte, CarteDocument } din„./carte.model”;@Injectabil()
exportclasă BookService {
constructor(@InjectModel(Nume carte) privat bookModel: Model) { }asincron Găsiți toate(): Promisiune
{
întoarcereacest.bookModel.find().exec();
}
asincron findOne (id: şir): Promisiune
{
întoarcereacest.bookModel.findById (id).exec();
}
}
De asemenea, trebuie să adăugați BookResolver la lista de furnizori din cărți.modul.ts.
import { Modulul } din„@nestjs/common”;
import { MongooseModule } din„@nestjs/mongoose”;
import { BookService } din„./books.service”;
import { BookResolver } din„./books.resolver”;
import { Book, BookSchema } din„./carte.model”;@Modul({
furnizori: [
BookService,
BookResolver
],
importuri: [MongooseModule.forFeature([
{
nume: Book.name,
schema: BookSchema,
},
]),
],
})
exportclasă Modulul Cărți {}
Lucrul cu mutații
În timp ce utilizați o interogare pentru a prelua date în GraphQL, mutațiile creează sau actualizează date în baza de date. Pentru a crea mutații, trebuie să acceptați date de la utilizatori. The Tip de introducere Decorator, care transformă o clasă într-un tip de intrare GraphQL, este util aici.
// carte.input.ts
import { InputType, Field } din„@nestjs/graphql”;@Tip de introducere()
exportclasă BookInput {
@Camp()
titlu: şir;@Camp()
autor: şir;
@Camp()
date publicate: boolean
}
Acum puteți actualiza cărți.resolver.ts sa arate asa:
import { Resolver, Query, Mutation, Args, ID } din„@nestjs/graphql”;
import { Carte } din„./carte.model”;
import { BookService } din„./books.service”;
import { BookInput } din„./book.input”;@Resolver(() => Carte)
exportclasă BookResolver {
constructor(privat readonly bookService: BookService) { }@Mutaţie(() => Carte)
asincron createBook(@Args('intrare') intrare: BookInput): Promisiune{
întoarcereacest.bookService.create (input);
}@Mutaţie(() => Carte)
asincron updatebook(
@Args('id', { tip: () => Am facut: şir,
@Args('intrare') intrare: BookInput,
): Promisiune{
întoarcereacest.bookService.update (id, intrare);
}
@Mutaţie(() => Carte)
asincron sterge cartea(@Args('id', { tip: () => Am facut: şir): Promisiune{
întoarcereacest.bookService.delete (id);
}
}
Și cărți.serviciu.ts ca aceasta:
import { injectabil } din„@nestjs/common”;
import { InjectModel } din„@nestjs/mongoose”;
import { Model } din'mangustă';
import { Carte, CarteDocument } din„./carte.model”;@Injectabil()
exportclasă BookService {
constructor(@InjectModel(Nume carte) privat bookModel: Model) { }asincron creați (carte: carte): Promisiune
{
const carte nouă = nouacest.bookModel (carte);
întoarcere newBook.save();
}asincron actualizare (id: şir, carte carte): Promisiune
{
întoarcereacest.bookModel.findByIdAndUpdate (id, carte, { nou: Adevărat }).exec();
}
asincronșterge(id: şir): Promisiune
{
întoarcereacest.bookModel.findByIdAndDelete (id).exec();
}
}
The @Mutaţie decoratorul marchează o funcție ca tip de mutație și @Args decoratorul preia orice intrări trecute în funcție.
În cele din urmă, ar trebui să importați Modulul Cărți în AppModule pentru a-l face funcțional. De asemenea, ar trebui să treci Modulul Cărți la pentruRootAsync după cum se vede mai jos.
import { Modulul Cărți } din„./books/books.module”;
/**
* alte importuri
*/@Modul({
importuri: [
ConfigModule.forRoot({
încărcare: [mongodbConfig],
isGlobal: Adevărat
}),
NestGraphQLModule.forRootAsync({
șofer: ApolloDriver,
injectați: [ConfigService],
useFactory: asincron (configService: ConfigService) => ({
autoSchemaFile: join (process.cwd(), „src/schema.gql”),
install SubscriptionHandlers: Adevărat,
sortSchema: Adevărat,
loc de joaca: Adevărat,
depanare: configService.get<boolean>(„DEBUG”),
încărcări: fals,
}),
}),
MongooseModule.forRootAsync({
injectați: [ConfigService],
useFactory: asincron (configService: ConfigService) => ({
uri: configService.get(„MONGO_URI”)
})
}),
Modulul Cărți,
],
controlere: [AppController],
furnizori: [AppService],
})
exportclasă AppModule {}
Puteți testa codul rulând npm run start: dev în terminalul dvs., iar aplicația dvs. ar trebui să înceapă cu succes pe port 3000.
Deschis localhost: 3000/graphql în browser pentru a afișa Graphiql interfață unde puteți testa interogări și mutații. Iată un exemplu care arată o interogare:
Și iată un exemplu de mutație:
Creați API-uri eficiente cu NestJS și GraphQL
Construirea unui API GraphQL în NestJS cu MongoDB folosind Mongoose implică definirea unei scheme pentru API-ul GraphQL, o schemă pentru modelul Mongoose, un serviciu pentru a interacționa cu baza de date și un resolver pentru a mapa operațiunile GraphQL la serviciu metode.
NestJS are funcționalități încorporate pentru construirea de API-uri, inclusiv decoratori pentru definirea rutelor, paznici pentru a le proteja și middleware pentru gestionarea cererilor și răspunsurilor. De asemenea, acceptă alte baze de date precum PostgreSQL, MySQL și SQLite, precum și alte biblioteci GraphQL precum Apollo și TypeGraphQL.