参考文档官网文档尝试遇到问题:
1、返回null的问题可以通过nullable: true解决
2、返回的数据跟schema 中定义的预期 types类型不一致,主要是由于之前在result.interceptor.ts中自定义返回数据格式导致,做下区分就可以了。
app.module.ts
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { SuppliesModule } from '../supplies/supplies.module'; const GQLModule = GraphQLModule.forRootAsync({ useFactory: () => ({ debug: true, playground: true, installSubscriptionHandlers: true, autoSchemaFile: 'schema.gql', tracing: true, include: [SuppliesModule], }), }); @Module({ imports: [ GQLModule, ], }) export class AppModule {}
supplies.resolver.ts
import { NotFoundException } from '@nestjs/common'; import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql'; import { PubSub } from 'apollo-server-express'; import { NewSupplieInput } from '../dto/supplie.input'; import { SupplieArgs } from '../dto/supplie.args'; import { Supplie } from '../models/supplie.model'; import { SuppliesService } from '../service/supplies.service'; const pubSub = new PubSub(); @Resolver((of) => Supplie) export class SuppliesResolver { constructor(private readonly suppliesService: SuppliesService) {} // @UseGuards(GqlAuthGuard) @Query((returns) => String) hello(): string { return 'Hello World!'; } // 查询单个 @Query((returns) => Supplie, { name: 'supplie', nullable: true }) async supplie(@Args('id') id: string): Promise<Supplie> { const supplie = await this.suppliesService.findOneById(id); if (!supplie) { throw new NotFoundException(id); } return supplie; } // 查询所有 @Query((returns) => [Supplie]) async suppliesAll(@Args() supplieArgs: SupplieArgs): Promise<Supplie[]> { return this.suppliesService.findAll(supplieArgs); } // 添加 @Mutation((returns) => Supplie) async addSupplie(@Args('newSupplieData') newSupplieData: NewSupplieInput): Promise<Supplie> { const supplie = await this.suppliesService.create(newSupplieData); pubSub.publish('suplieAdded', { suplieAdded: supplie }); return supplie; } // 删除 @Mutation((returns) => Boolean) async removeSupplie(@Args('id') id: string) { return this.suppliesService.remove(id); } @Subscription((returns) => Supplie) suplieAdded() { return pubSub.asyncIterator('suplieAdded'); } }
supplies.service.ts
import { Injectable } from '@nestjs/common'; import { NewSupplieInput } from '../dto/supplie.input'; import { SupplieArgs } from '../dto/supplie.args'; import { Supplie } from '../models/supplie.model'; @Injectable() export class SuppliesService { private readonly supplies: Supplie[] = [{ id: 1, firstName: 'Cat', lastName: '5' }]; async create(data: NewSupplieInput): Promise<Supplie> { return {} as any; } async findOneById(id: string): Promise<Supplie> { // return this.supplies.find((supplie) => supplie.id === id); return this.supplies[0]; } async findAll(supplieArgs: SupplieArgs): Promise<Supplie[]> { const result = [ { id: 100, firstName: 'ddd', lastName: 'ddf' }, { id: 11, firstName: 'ddd', lastName: 'ddf' }, ]; return result; } async remove(id: string): Promise<boolean> { return true; } }
supplies.module.ts
import { Module } from '@nestjs/common'; import { SuppliesResolver } from './resolver/supplies.resolver'; import { SuppliesService } from './service/supplies.service'; @Module({ providers: [SuppliesResolver, SuppliesService], }) export class SuppliesModule {}
supplie.model.ts
import { Field, Int, ObjectType } from '@nestjs/graphql'; @ObjectType() export class Supplie { @Field((type) => Int) id?: number; @Field({ nullable: true }) firstName: string; @Field({ nullable: true }) lastName: string; }
supplie.args.ts
import { ArgsType, Field, Int } from '@nestjs/graphql'; import { Max, Min } from 'class-validator'; @ArgsType() export class SupplieArgs { @Field((type) => Int) @Min(0) skip: number = 0; @Field((type) => Int) @Min(1) @Max(50) take: number = 25; }
supplie.input.ts
import { Field, InputType } from '@nestjs/graphql'; import { IsOptional, Length, MaxLength } from 'class-validator'; @InputType() export class NewSupplieInput { @Field() @MaxLength(30) name: string; @Field({ nullable: true }) @IsOptional() @Length(30, 255) firstName?: string; @Field((type) => String) lastName: string; }
result.interceptor.ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable, from } from 'rxjs'; import { map } from 'rxjs/operators'; import { GqlContextType } from '@nestjs/graphql'; export interface Response<T> { data: T; } @Injectable() export class ResultInterceptor<T> implements NestInterceptor<T, Response<T>> { intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> { // HTTP (REST) Context if (context.getType() === 'http') { return next.handle().pipe( map((rawData) => ({ code: (rawData && rawData.code) || 100000, msg: (rawData && rawData.msg) || 'success', currTime: new Date(), data: rawData ? (!rawData.code && !rawData.msg ? rawData : rawData.data || undefined) : undefined, })) ); } // GraphQL Context else if (context.getType<GqlContextType>() === 'graphql') { eturn next.handle(); } return next.handle(); } }
二、在 Vue 组件中的用法
<template> <div>{{ hello }}</div> </template> <script> import gql from 'graphql-tag' export default { apollo: { // 简单的查询,将更新 'hello' 这个 vue 属性 hello: gql`query { hello }`, }, } </script>
query { supplie(id: "1") { firstName, lastName, id } hello }
query SuppliesAll($pageIndex: Int!) { suppliesAll(skip: $pageIndex) { id, lastName } }
Query Variables
{
"pageIndex": 1
}
参考:
vue Apollo https://vue-apollo.netlify.com/zh-cn/guide/apollo
NestJS GraphQL https://docs.nestjs.com/graphql/resolvers
GraphQL快速入门 https://segmentfault.com/a/1190000017851838
VUE与GQLhttps://www.cnblogs.com/lhxsoft/p/11904388.html