使用NestJS开发GraphQL服务器(代码优先版)
GraphQL的基础。
GraphQL执行API作为严格定义类型的模式,而不是像REST端点一样在繁琐管理的端点上。
不深入解释GraphQL,但以下链接非常有参考价值。建议初学者阅读一次。
-
- 公式
-
- チュートリアル
- youtubeのチュートリアル
使用NestJS开发GraphQL
使用NestJS开发GraphQL有两种方法。
-
- スキーマファースト
- コードファースト
在Schema First的方法中,我们使用GraphQL SDL(Schema Definition Language)来自动生成TypeScript定义。而在Code First的方法中,我们只使用装饰器和TypeScript类来生成相应的GraphQL Schema。
本次我们将使用代码优先的方式来创建GraphQL服务器。
首先,让我们安装nestjs的命令行工具@nestjs/cli。安装完成后,您就可以使用nest命令了。现在就来创建一个NestJS应用程序。
$ npm i -g @nestjs/cli
$ nest new nest-graphql
我们来运行已创建的NestJS应用程序。
$ cd nest-graphql/
$ npm run start
> nest-graphql@0.0.1 start /Users/daisuke/work/nest-graphql
> ts-node -r tsconfig-paths/register src/main.ts
[Nest] 5868 - 2019-12-03 21:36:33 [NestFactory] Starting Nest application...
[Nest] 5868 - 2019-12-03 21:36:33 [InstanceLoader] AppModule dependencies initialized +28ms
[Nest] 5868 - 2019-12-03 21:36:33 [RoutesResolver] AppController {/}: +10ms
[Nest] 5868 - 2019-12-03 21:36:33 [RouterExplorer] Mapped {/, GET} route +16ms
[Nest] 5868 - 2019-12-03 21:36:33 [NestApplication] Nest application successfully started +6ms
安装与GraphQL相关的库
由于我们要实现GraphQL服务器,所以首先需要安装必要的库。
$ npm i --save @nestjs/graphql \
apollo-server-express \
graphql-tools
让我们修改 app.module.ts 文件,以适应 REST API。
我们将 Controller 和 Service 替换为 GraphQLModule。
通过 .forRoot() 方法声明 playground: true,可以在浏览器(http://localhost:3000/graphql)中显示 GraphQL IDE。autoSchemaFile 表示自动生成的模式将被创建在指定的路径上。
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
imports: [
GraphQLModule.forRoot({
playground: true,
autoSchemaFile: 'schema.graphql'
}),
],
})
export class AppModule {}
当应用程序在后台运行时,可以在Web浏览器中打开http://localhost:3000/graphql并显示Playground。请执行npm run start启动应用程序,并尝试在浏览器中打开。
$ npm run start
> nest-graphql@0.0.1 start /Users/daisuke/work/nest-graphql
> ts-node -r tsconfig-paths/register src/main.ts
[Nest] 8832 - 2019-12-03 23:44:15 [NestFactory] Starting Nest application...
[Nest] 8832 - 2019-12-03 23:44:15 [InstanceLoader] AppModule dependencies initialized +26ms
[Nest] 8832 - 2019-12-03 23:44:15 [InstanceLoader] RecipesModule dependencies initialized +1ms
[Nest] 8832 - 2019-12-03 23:44:15 [InstanceLoader] GraphQLModule dependencies initialized +0ms
[Nest] 8832 - 2019-12-03 23:44:15 [NestApplication] Nest application successfully started +82ms
创建一个模块。
按照 NestJS 的方式,首先创建一个 Module。我们以显示食谱列表的应用程序为例。
$ nest generate module recipes
CREATE /src/recipes/recipes.module.ts (84 bytes)
UPDATE /src/app.module.ts (325 bytes)
请确认app.module.ts是否自动添加了RecipesModule。
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { RecipesModule } from './recipes/recipes.module';
@Module({
imports: [
GraphQLModule.forRoot({
playground: true,
autoSchemaFile: 'schema.graphql',
}),
RecipesModule, // <-- 自動的に追加される
],
})
export class AppModule {}
创建模型
接下来,我们将创建一个模型。
从 @nestjs/graphql 库中导入使用各种装饰器进行声明的内容。
$ nest generate class recipes/recipe
CREATE /src/recipes/recipe.spec.ts (147 bytes)
CREATE /src/recipes/recipe.ts (23 bytes)
import { Field, ID, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class Recipe {
@Field(type => ID)
id: string;
@Field()
title: string;
}
创建一个Resolver
我們會創建一個解析器來執行最後的查詢操作。
$ nest generate resolver recipes
CREATE /src/recipes/recipes.resolver.spec.ts (477 bytes)
CREATE /src/recipes/recipes.resolver.ts (98 bytes)
UPDATE /src/recipes/recipes.module.ts (170 bytes)
为了这个解析器,我们将实现查询、突变和订阅。
为了简单起见,本次不连接数据库,而是实现一个返回食谱列表的查询处理(Query)。
import { Resolver, Query, Args } from '@nestjs/graphql';
import { Recipe } from './recipe';
const recipeTable = [
{
id: '1',
title: '鯖の味噌煮',
},
{
id: '2',
title: 'ミートソーススパゲティ',
},
{
id: '3',
title: '豚の生姜焼',
},
];
@Resolver('Recipes')
export class RecipesResolver {
@Query(returns => [Recipe])
async recipes(): Promise<Recipe[]> {
return recipeTable;
}
}
到目前为止,目录结构如下所示。
$ tree -L 2
.
├── app.module.ts
├── main.ts
└── recipes
├── recipe.spec.ts
├── recipe.ts
├── recipes.module.ts
├── recipes.resolver.spec.ts
└── recipes.resolver.ts
创建模式
当您启动该应用程序时,它会自动创建模式。
$ npm run start
在 schema.graphql 中自动创建了一个模式。
# -----------------------------------------------
# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!
# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!!
# -----------------------------------------------
type Query {
recipes: [Recipe!]!
}
type Recipe {
id: ID!
title: String!
}
通过使用NestJS,只需为模型添加装饰器,就能简单而轻松地进行实现。
通过正确使用依赖注入,NestJS是一个强大的框架,可以提高代码的可测试性。
在构建GraphQL服务器时,它可能展现出强大的能力,非常有吸引力。