使用NestJS开发GraphQL服务器(代码优先版)

nestjs-graphql.gif

GraphQL的基础。

GraphQL执行API作为严格定义类型的模式,而不是像REST端点一样在繁琐管理的端点上。

image.png

不深入解释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
image.png

安装与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
image.png

创建一个模块。

按照 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-graphql.gif

通过使用NestJS,只需为模型添加装饰器,就能简单而轻松地进行实现。

通过正确使用依赖注入,NestJS是一个强大的框架,可以提高代码的可测试性。
在构建GraphQL服务器时,它可能展现出强大的能力,非常有吸引力。

广告
将在 10 秒后关闭
bannerAds