Създайте свой собствен API, като използвате тези популярни уеб технологии.

GraphQL и NestJS създават отлично партньорство, което ви дава солидна основа за вашите API и лесна за използване рамка за изграждане на мащабируеми уеб приложения. Комбинацията е перфектна за изграждане на готови за производство приложения и двете са много подходящи инструменти в днешната технологична екосистема.

Научете повече за това как можете да създадете API, като използвате и двата продукта.

Какво е GraphQL?

GraphQL е език за заявки и манипулиране на данни можете да използвате за изграждане на API по по-прецизен и стегнат начин. GraphQL предоставя пълно и адекватно описание на съществуващите данни в API и дава възможност на клиента да получи точните необходими данни.

GraphQL предоставя много функции, които липсват на REST API, вариращи от прецизни заявки за данни до по-добри инструменти за разработчици, като graphiql редактор. Освен това ви позволява да правите заявки за множество ресурси чрез една заявка.

Какво е NestJS?

instagram viewer

NestJS е прогресивна Node.js рамка, която можете да използвате за изграждане на мащабируеми и ефективни приложения от страна на сървъра. NestJS предоставя много плъгини, заедно с инструменти за бързо и лесно развитие, включително поддръжка на GraphQL, GRPC, WebSockets и др.

NestJS е добре известен в екосистемата със своята оптимизирана структура на проекта, използваща модули, контролери, услуги и схеми. Неговият вграден CLI ви позволява да създадете структурирана API архитектура. Можеш да използваш принципи на инжектиране на зависимости за да контролирате как частите на приложението комуникират помежду си.

Внедряване на GraphQL с NestJS и MongoDB

Преди да създадете API с NestJS и GraphQL, ще трябва да имате налични правилните зависимости. имате нужда за да инсталирате Node.js и NestJS, които можете да инсталирате, като стартирате npm i -g @nestjs/cli.

Примерът, който следва, е просто приложение, което съхранява информация за книги. Изпълнете следната команда във вашия терминал, за да създадете ново NestJS приложение:

гнездо ново 

Придвижете се до директорията на генерираното приложение () и инсталирайте неговите зависимости със следната команда:

$ npm install --save @nestjs/config @nestjs/graphql graphql-инструменти graphql \
 @nestjs/apollo apollo-server-express @nestjs/mongoose @types/graphql

Има два основни подхода за изграждане на GraphQL API, а именно:

  1. Схема-първи подход: където описвате API във файлове с дефиниции на схеми или SDL, а NestJS генерира дефиниции на Typescript въз основа на тях.
  2. Подход на първи код: където дефинирате заявки, мутации и други функционалности на GraphQL с помощта на класове и декоратори на Typescript, а NestJS генерира SDL файлове въз основа на тях.

Следващият пример описва как да използвате подход на първо място с код.

Първо, трябва да инициализирате GraphQL във вашия AppModule и свържете го към база данни MongoDB:

// app.module.ts
импортиране { Модул } от„@nestjs/common“;
импортиране { GraphQLModule като NestGraphQLModule } от'@nestjs/graphql';
импортиране { ApolloDriver, ApolloDriverConfig } от„@nestjs/apollo“;
импортиране { присъединяване } от"път";
импортиране { MongooseModule } от„@nestjs/mongoose“;
импортиране { AppController } от'./app.controller';
импортиране { AppService } от'./app.service';
импортиране {ConfigModule, ConfigService} от„@nestjs/config“;
импортиране mongodbConfig от'./config/mongodb.config';

@Модул({
внос: [
ConfigModule.forRoot({
зареждане: [mongodbConfig],
isGlobal: вярно
}),
NestGraphQLModule.forRootAsync({
драйвер: ApolloDriver,
инжектиране: [ConfigService],
useFactory: асинхронен (configService: ConfigService) => ({
autoSchemaFile: присъединяване (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: вярно,
sortSchema: вярно,
игрище: вярно,
отстраняване на грешки: configService.get<булево>(„ОТСТРАНЯВАНЕ НА ГРЕШКИ“),
качвания: невярно,
}),
}),
MongooseModule.forRootAsync({
инжектиране: [ConfigService],
useFactory: асинхронен (configService: ConfigService) => ({
uri: configService.get(„MONGO_URI“)
})
}),
],
контролери: [AppController],
доставчици: [AppService],
})

износклас AppModule {}

Този модул импортира GraphQLModule от @nestjs/graphql и на MongooseModule от @nestjs/монгуста което помага за свързване с MongoDB. The autoSchemaFile свойство указва местоположението на генерирания файл на схемата и sortSchema свойство гарантира, че подрежда полетата по азбучен ред.

Ето какво представлява вашата MongoDB конфиг файлът трябва да изглежда така:

импортиране { registerAs } от„@nestjs/config“;

/**
 * Конфигурация за връзка с базата данни на Mongo
 */
износпо подразбиране registerAs("mongodb", () => {
конст {
MONGO_URI
} = process.env;

връщане {
uri: `${MONGO_URI}`,
};
});

Дефиниране на GraphQL схема

След като настроите връзките GraphQL и MongoDB, трябва да дефинирате заявки и мутации на GraphQL, за да генерирате схема (schema.gql) файл.

Писане на запитвания

В код-първи подход, създавате модел с помощта на ObjectType декоратор. По-късно ще трансформирате този модел в тип GraphQL.

Например:

// book.model.ts
импортиране { поле, тип обект } от'@nestjs/graphql';
импортиране { Prop, Schema, SchemaFactory } от„@nestjs/mongoose“;
импортиране {Документ} от"мангуста";

износТип BookDocument = Книга и документ;

@ObjectType()
@Схема()
износклас Книга {
@Поле()
заглавие: низ;

@Поле()
автор: низ;

@Поле()
Дата на публикуване: булево;
}

износконст BookSchema = SchemaFactory.createForClass (Книга);

GraphQL по подразбиране не може да използва създадените схеми. За да ги направите функционални, имате нужда от услуга за преобразуване, която съдържа функциите за изпълнение на типовете GraphQL. Можете да направите това с Резолвер декоратор.

// books.resolver.ts
импортиране { Разрешител, заявка, мутация, аргументи, ID } от'@nestjs/graphql';
импортиране { Книга } от'./book.model';
импортиране { BookService } от'./books.service';

@Разрешител(() => Книга)
износклас BookResolver {
конструктор(частен bookService само за четене: BookService) { }

@Query(() => [Книга])
асинхронен книги(): обещание {
връщанетова.bookService.findAll();
}

@Query(() => Книга)
асинхронен Книга(@Args('документ за самоличност', { Тип: () => Направих: низ): обещание {
връщанетова.bookService.findOne (id);
}
}

Можете да приложите BookService, внесен по-горе, както следва:

// books.service.ts
импортиране { Инжекционен } от„@nestjs/common“;
импортиране { InjectModel } от„@nestjs/mongoose“;
импортиране { Модел } от"мангуста";
импортиране {Книга, BookDocument} от'./book.model';

@Инжекционен()
износклас BookService {
конструктор(@InjectModel(Книга.име) частен bookModel: Модел) { }

асинхронен findAll(): обещание {
връщанетова.bookModel.find().exec();
}

асинхронен findOne (id: низ): обещание {
връщанетова.bookModel.findById (id).exec();
}
}

Трябва също да добавите BookResolver към списъка с доставчици в books.module.ts.

импортиране { Модул } от"@nestjs/common";
импортиране { MongooseModule } от"@nestjs/mongoose";
импортиране { BookService } от'./books.service';
импортиране { BookResolver } от'./books.resolver';
импортиране {Книга, BookSchema} от'./book.model';

@Модул({
доставчици: [
BookService,
BookResolver
],
импортира: [MongooseModule.forFeature([
{
име: Book.name,
схема: BookSchema,
},
]),
],
})

износклас КнигиМодул {}

Работа с мутации

Докато използвате заявка за извличане на данни в GraphQL, мутациите създават или актуализират данни в базата данни. За да създадете мутации, трябва да приемете данни от потребители. The InputType декораторът, който превръща клас във входен тип GraphQL, е полезен тук.

// book.input.ts
импортиране { InputType, Field } от'@nestjs/graphql';

@InputType()
износклас BookInput {
@Поле()
заглавие: низ;

@Поле()
автор: низ;

@Поле()
Дата на публикуване: булево
}

Вече можете да актуализирате books.resolver.ts да изглежда така:

импортиране { Разрешител, заявка, мутация, аргументи, ID } от'@nestjs/graphql';
импортиране { Книга } от'./book.model';
импортиране { BookService } от'./books.service';
импортиране { BookInput } от'./book.input';

@Разрешител(() => Книга)
износклас BookResolver {
конструктор(частен bookService само за четене: BookService) { }

@Мутация(() => Книга)
асинхронен createBook(@Args('вход') вход: BookInput): обещание {
връщанетова.bookService.create (вход);
}

@Мутация(() => Книга)
асинхронен актуализацияКнига(
@Args('документ за самоличност', { Тип: () => Направих: низ,
@Args('вход') вход: BookInput,
): обещание {
връщанетова.bookService.update (id, вход);
}

@Мутация(() => Книга)
асинхронен изтрийКнига(@Args('документ за самоличност', { Тип: () => Направих: низ): обещание {
връщанетова.bookService.delete (id);
}
}

И books.service.ts като този:

импортиране { Инжекционен } от„@nestjs/common“;
импортиране { InjectModel } от„@nestjs/mongoose“;
импортиране { Модел } от"мангуста";
импортиране {Книга, BookDocument} от'./book.model';

@Инжекционен()
износклас BookService {
конструктор(@InjectModel(Книга.име) частен bookModel: Модел) { }

асинхронен създайте (книга: Книга): обещание {
конст нова книга = новтова.bookModel (книга);
връщане newBook.save();
}

асинхронен актуализация (id: низ, книга: Книга): обещание {
връщанетова.bookModel.findByIdAndUpdate (id, книга, { нов: вярно }).exec();
}

асинхроненИзтрий(документ за самоличност: низ): обещание {
връщанетова.bookModel.findByIdAndDelete (id).exec();
}
}

The @Мутация декораторът маркира функция като тип мутация и @Args декораторът хваща всички входове, предадени на функцията.

И накрая, трябва да импортирате КнигиМодул в AppModule за да стане функционален. Трябва също да преминете КнигиМодул да се forRootAsync както се вижда по-долу.

импортиране { BooksModule } от'./books/books.module';
/**
 * друг внос
*/

@Модул({
внос: [
ConfigModule.forRoot({
зареждане: [mongodbConfig],
isGlobal: вярно
}),
NestGraphQLModule.forRootAsync({
драйвер: ApolloDriver,
инжектиране: [ConfigService],
useFactory: асинхронен (configService: ConfigService) => ({
autoSchemaFile: присъединяване (process.cwd(), 'src/schema.gql'),
installSubscriptionHandlers: вярно,
sortSchema: вярно,
игрище: вярно,
отстраняване на грешки: configService.get<булево>(„ОТСТРАНЯВАНЕ НА ГРЕШКИ“),
качвания: невярно,
}),
}),
MongooseModule.forRootAsync({
инжектиране: [ConfigService],
useFactory: асинхронен (configService: ConfigService) => ({
uri: configService.get(„MONGO_URI“)
})
}),
КнигиМодул,
],
контролери: [AppController],
доставчици: [AppService],
})

износклас AppModule {}

Можете да тествате кода, като стартирате npm стартиране стартиране: dev във вашия терминал и вашето приложение трябва да стартира успешно на порт 3000.

Отворете локален хост: 3000/graphql във вашия браузър, за да покажете Graphiql интерфейс, където можете да тествате заявки и мутации. Ето един пример, който показва заявка:

И ето пример за мутация:

Изградете ефективни API с NestJS и GraphQL

Изграждането на GraphQL API в NestJS с MongoDB с помощта на Mongoose включва дефиниране на схема за GraphQL API, схема за модела Mongoose, услуга за взаимодействие с базата данни и резолвер за картографиране на GraphQL операции към услуга методи.

NestJS има вградена функционалност за изграждане на API, включително декоратори за дефиниране на маршрути, предпазители за защитата им и междинен софтуер за обработка на заявки и отговори. Той също така поддържа други бази данни като PostgreSQL, MySQL и SQLite, както и други библиотеки на GraphQL като Apollo и TypeGraphQL.