目標:
在 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 !