iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0
Modern Web

NestJs 讀書筆記系列 第 10

NestJs - GraphQL 內部結構說明 (下篇)

  • 分享至 

  • xImage
  •  

GraphQL 內部結構說明 (下篇)

目標:

  1. 了解 GraphQL Schema first 模式,成功在 Playground 發送 API

Schema first

在 GraphQLModule 加入 typePaths,讓 GraphQLModule 能夠找到定義好的 GraphQL SDL schema
加入 definitions 屬性,指定編譯後要寫入的位置

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),

NestJs 還提供了 GraphQLDefinitionsFactory 方法
我們希望能降低模組間的耦合性,所以把產生 TypeScript output 獨立出來

// Path: src/generate-typings.ts

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
    // graphql 文件位置
    typePaths: ['./src/**/*.graphql'],
    // 編譯後寫入的路徑
    path: join(process.cwd(), 'src/graphql.schema.ts'),
    // 輸出格式為 class,預設是抽象類型
    outputAs: 'class',
    // 開啟隨時監聽
    watch: true,
});

package.json 腳本中多一個指令來執行 ts-node src/generate-typings

{
  "scripts": {
    "generate:typings": "ts-node src/generate-typings",
  }
}

終端機執行 yarn generate:typings,然後就完美的失敗!!
別緊張,我們只是還沒建立 .graphql 檔案而已
接著建立 authors.graphql

# Path : src/authors/authors.graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
}

type Query {
  author(id: Int!): Author
}

再執行 yarn generate:typings ,相信這次就能完美成功了!
graphql.schema.ts 就是編譯成功的結果

// Path: src/graphql.schema.ts

/** ------------------------------------------------------
 * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
 * -------------------------------------------------------
 */

/* tslint:disable */
/* eslint-disable */
export class Author {
    id: number;
    firstName?: string;
    lastName?: string;
}

export abstract class IQuery {
    abstract author(id: number): Author | Promise<Author>;
}

Resolver

跟之前 Code firest 一樣,就不多加以說明

import { Resolver, Query, Args, ID } from "@nestjs/graphql";
import { AuthrosSerivce } from './authors.service';
@Resolver('Author')
export class AuthorsResolver {
    constructor (
        private authrosSerivce: AuthrosSerivce,
    ) {}

    @Query()
    async author(@Args('id', { type: () => ID }) id: string) {
        return this.authrosSerivce.findOneById(id);
    }
}

Service

將 graphql.schema 引入,使用 Author 作為函式回傳格式

import { Injectable } from '@nestjs/common';
import { Author } from '../graphql.schema';

@Injectable()
export class AuthrosSerivce {
    async findOneById(id: String): Promise<Author> {
        return {
            id: "1",
            lastName: "lastName",
            firstName: "firstName"
        };
    }
}

Module

最後把 AuthrosSerivce, AuthorsResolver 放入 providers

import { Module } from '@nestjs/common';
import { AuthrosSerivce } from './authors.service';
import { AuthorsResolver } from './authors.resolver';
@Module({
    providers: [AuthrosSerivce, AuthorsResolver]
})
export class AuthorsModule {}

Playground

打開Playground 進行測試,就能成功獲取 author 物件!

結尾

這兩篇就是 Code first 以及 Schema first 介紹
至於讀者會思考,我的專案用哪一種比較好,我認為是看個人喜好吧
有些人可能還是習慣寫 Graphql Schema,有些人則偏好另一種形式
如果有想法的讀者歡迎在下方留言一起討論!

到目前為止,基本的 CRUD 都已經實現了
接著會介紹 NestJs 的 Subscriptions !


上一篇
NestJs - GraphQL 內部結構說明 (上篇)
下一篇
NestJs - GraphQL 內部結構說明 (Subscription篇)
系列文
NestJs 讀書筆記31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言