目標:
在 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>;
}
跟之前 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);
    }
}
將 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"
        };
    }
}
最後把 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 進行測試,就能成功獲取 author 物件!

這兩篇就是 Code first 以及 Schema first 介紹
至於讀者會思考,我的專案用哪一種比較好,我認為是看個人喜好吧
有些人可能還是習慣寫 Graphql Schema,有些人則偏好另一種形式
如果有想法的讀者歡迎在下方留言一起討論!
到目前為止,基本的 CRUD 都已經實現了
接著會介紹 NestJs 的 Subscriptions !