惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Secure Thoughts
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
美团技术团队
G
Google Developers Blog
宝玉的分享
宝玉的分享
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
小众软件
小众软件
Google DeepMind News
Google DeepMind News
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
Webroot Blog
Webroot Blog
D
DataBreaches.Net
IT之家
IT之家
PCI Perspectives
PCI Perspectives
人人都是产品经理
人人都是产品经理
Hacker News: Ask HN
Hacker News: Ask HN
L
LangChain Blog
SecWiki News
SecWiki News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
T
Threatpost
P
Proofpoint News Feed
Y
Y Combinator Blog
Cloudbric
Cloudbric
T
Tor Project blog
量子位
博客园_首页
B
Blog
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
D
Darknet – Hacking Tools, Hacker News & Cyber Security

博客园 - 稻草人.Net

Python多环境管理神器pyenv+poetry python包管理利器poetry和conda使用简介 Spring REST 接口自定义404不能捕获NoHandlerFoundException问题 MacOS 安装Podman 替代Docker Prettier + ESLint + TS常用配置项 React Native V0.64.4版本 开发环境搭建及问题 Nodejs环境Eggjs加签验签示例 Mac安装compass失败相关问题 MySQL手动安装方法 Docker+Jenkins更换国内插件源 Chrome91版本 SameSite cookies 被移除后的解决方法 推荐几个文档中心搭建工具 前端开发Docker快速入门(二)制作镜像并创建容器 微信开放平台-第三方平台代小程序实现业务 微信开放平台-第三方平台授权流程及接口概述 Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王 Mac安装Arduino搭建ESP8266 NodeMCU开发环境 用vscode进行jest单元测试并调试代码 vscode配置typescript和eslint的环境
尝试使用Nestjs搭建GraphQL服务
稻草人.Net · 2020-06-19 · via 博客园 - 稻草人.Net

参考文档官网文档尝试遇到问题:

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