Nest.js 框架 GraphQL 支持

person 无限可能    watch_later 2024-10-06 15:41:14
visibility 126    class GraphQL    bookmark 专栏

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