Nest.js 提供了对 GraphQL 的良好支持,允许我们轻松构建功能丰富的 GraphQL API。通过集成 GraphQL,我们可以实现灵活的数据查询和操作,满足现代应用的需求。本文将详细介绍如何在 Nest.js 中集成 GraphQL,并创建一个简单的 GraphQL API。
GraphQL 是一种用于 API 的查询语言和运行时,可以通过单个端点处理复杂的数据查询。与 REST API 相比,GraphQL 允许客户端指定所需的数据结构,从而减少了数据传输量和请求次数。
首先,安装必要的依赖,包括 @nestjs/graphql
和 graphql
:
npm install @nestjs/graphql graphql apollo-server-express
我们将创建一个简单的图书管理 API,允许用户查询和添加书籍。
在 app.module.ts
中配置 GraphQL 模块:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { BooksModule } from './books/books.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Book } from './books/book.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'sqlite', // 使用 SQLite 数据库
database: 'data.db',
entities: [Book],
synchronize: true,
}),
GraphQLModule.forRoot({
autoSchemaFile: 'schema.gql', // 自动生成 GraphQL schema
}),
BooksModule,
],
})
export class AppModule {}
在这个配置中,我们使用 SQLite 作为数据库,并设置 GraphQL 模块自动生成 schema 文件。
在 books
文件夹中创建 book.entity.ts
:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
author: string;
@Column()
publishedDate: string;
}
在 books
文件夹中创建 books.service.ts
:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Book } from './book.entity';
@Injectable()
export class BooksService {
constructor(
@InjectRepository(Book)
private booksRepository: Repository<Book>,
) {}
findAll(): Promise<Book[]> {
return this.booksRepository.find();
}
create(book: Partial<Book>): Promise<Book> {
const newBook = this.booksRepository.create(book);
return this.booksRepository.save(newBook);
}
}
在 books
文件夹中创建 books.resolver.ts
:
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { BooksService } from './books.service';
import { Book } from './book.entity';
import { CreateBookInput } from './create-book.input';
@Resolver(() => Book)
export class BooksResolver {
constructor(private booksService: BooksService) {}
@Query(() => [Book])
async books(): Promise<Book[]> {
return this.booksService.findAll();
}
@Mutation(() => Book)
async createBook(@Args('input') input: CreateBookInput): Promise<Book> {
return this.booksService.create(input);
}
}
在 books
文件夹中创建 create-book.input.ts
:
import { InputType, Field } from '@nestjs/graphql';
@InputType()
export class CreateBookInput {
@Field()
title: string;
@Field()
author: string;
@Field()
publishedDate: string;
}
在 books
文件夹中创建 books.module.ts
:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BooksService } from './books.service';
import { BooksResolver } from './books.resolver';
import { Book } from './book.entity';
@Module({
imports: [TypeOrmModule.forFeature([Book])],
providers: [BooksService, BooksResolver],
})
export class BooksModule {}
确保 Nest.js 应用已启动:
npm run start
使用 GraphQL Playground 测试我们的 API。在浏览器中访问 http://localhost:3000/graphql
,可以进行如下操作:
query {
books {
id
title
author
publishedDate
}
}
mutation {
createBook(input: {
title: "Nest.js in Action",
author: "John Doe",
publishedDate: "2022-01-01"
}) {
id
title
author
publishedDate
}
}
GraphQL 还可以与 WebSocket 集成,构建实时应用。我们可以通过 @nestjs/subscriptions
来实现实时功能。
npm install @nestjs/graphql @nestjs/apollo graphql apollo-server-express subscriptions-transport-ws
在 app.module.ts
中更新 GraphQL 配置:
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: 'schema.gql',
subscriptions: {
'onConnect': (connectionParams, websocket) => {
console.log('Client connected');
},
},
}),
],
})
在 books
文件夹中创建 books.resolver.ts
的更新版本:
import { Resolver, Query, Mutation, Args, Subscription } from '@nestjs/graphql';
import { BooksService } from './books.service';
import { Book } from './book.entity';
import { CreateBookInput } from './create-book.input';
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver(() => Book)
export class BooksResolver {
constructor(private booksService: BooksService) {}
@Query(() => [Book])
async books(): Promise<Book[]> {
return this.booksService.findAll();
}
@Mutation(() => Book)
async createBook(@Args('input') input: CreateBookInput): Promise<Book> {
const newBook = await this.booksService.create(input);
pubSub.publish('bookAdded', { bookAdded: newBook });
return newBook;
}
@Subscription(() => Book, {
resolve: value => value,
filter: (payload, variables) => {
return true; // 可以添加过滤条件
},
})
bookAdded() {
return pubSub.asyncIterator('bookAdded');
}
}
在 GraphQL Playground 中测试订阅功能。
subscription {
bookAdded {
id
title
author
publishedDate
}
}
再执行创建书籍的 mutation,订阅会自动接收到新书籍的信息。
通过以上步骤,我们成功实现了一个基于 Nest.js 的 GraphQL API,并集成了实时功能。我们创建了图书管理模块,支持查询和添加书籍,利用 GraphQL 的灵活性和实时性,使我们的应用更加强大。
@nestjs/graphql
轻松构建 GraphQL API。Nest.js 与 GraphQL 的结合为开发现代 Web 应用提供了强大的工具,能够满足复杂的业务需求和实时通信的要求。通过不断扩展,我们可以进一步丰富功能,如添加用户管理、复杂查询等,实现更全面的解决方案。