Nest.js 框架 GraphQL 支持

class GraphQL

Nest.js 提供了对 GraphQL 的良好支持,允许我们轻松构建功能丰富的 GraphQL API。通过集成 GraphQL,我们可以实现灵活的数据查询和操作,满足现代应用的需求。本文将详细介绍如何在 Nest.js 中集成 GraphQL,并创建一个简单的 GraphQL API。

1. GraphQL 概述

GraphQL 是一种用于 API 的查询语言和运行时,可以通过单个端点处理复杂的数据查询。与 REST API 相比,GraphQL 允许客户端指定所需的数据结构,从而减少了数据传输量和请求次数。

2. 安装依赖

首先,安装必要的依赖,包括 @nestjs/graphqlgraphql

npm install @nestjs/graphql graphql apollo-server-express

3. 创建 GraphQL 模块

我们将创建一个简单的图书管理 API,允许用户查询和添加书籍。

3.1 设置 GraphQL 模块

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 文件。

3.2 创建书籍实体

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;
}

3.3 创建书籍服务

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);
  }
}

3.4 创建书籍解析器

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);
  }
}

3.5 创建输入类型

books 文件夹中创建 create-book.input.ts

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class CreateBookInput {
  @Field()
  title: string;

  @Field()
  author: string;

  @Field()
  publishedDate: string;
}

3.6 创建书籍模块

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 {}

4. 运行应用

确保 Nest.js 应用已启动:

npm run start

5. 测试 GraphQL API

使用 GraphQL Playground 测试我们的 API。在浏览器中访问 http://localhost:3000/graphql,可以进行如下操作:

5.1 查询所有书籍

query {
  books {
    id
    title
    author
    publishedDate
  }
}

5.2 创建新书籍

mutation {
  createBook(input: {
    title: "Nest.js in Action",
    author: "John Doe",
    publishedDate: "2022-01-01"
  }) {
    id
    title
    author
    publishedDate
  }
}

6. 实现实时功能

GraphQL 还可以与 WebSocket 集成,构建实时应用。我们可以通过 @nestjs/subscriptions 来实现实时功能。

6.1 安装依赖

npm install @nestjs/graphql @nestjs/apollo graphql apollo-server-express subscriptions-transport-ws

6.2 更新 GraphQL 模块以支持订阅

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');
        },
      },
    }),
  ],
})

6.3 创建订阅解析器

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');
  }
}

7. 测试实时订阅

在 GraphQL Playground 中测试订阅功能。

7.1 订阅新书籍的添加

subscription {
  bookAdded {
    id
    title
    author
    publishedDate
  }
}

7.2 创建新书籍

再执行创建书籍的 mutation,订阅会自动接收到新书籍的信息。

8. 总结

通过以上步骤,我们成功实现了一个基于 Nest.js 的 GraphQL API,并集成了实时功能。我们创建了图书管理模块,支持查询和添加书籍,利用 GraphQL 的灵活性和实时性,使我们的应用更加强大。

  • GraphQL 集成:通过 @nestjs/graphql 轻松构建 GraphQL API。
  • 输入类型:使用输入类型简化请求参数的管理。
  • 实时订阅:通过 PubSub 模块实现实时数据推送。

Nest.js 与 GraphQL 的结合为开发现代 Web 应用提供了强大的工具,能够满足复杂的业务需求和实时通信的要求。通过不断扩展,我们可以进一步丰富功能,如添加用户管理、复杂查询等,实现更全面的解决方案。

评论区
评论列表
menu