如果你使用Typescript + Graphql,那么我推荐使用TypeGraphql

首先

Graphql是我个人非常喜欢并持续使用的技术。

・与TypeScript不太相兼容
・使用ORM时需要定义ORM,还需要定义GraphQL的模式,所以非常麻烦
・模式定义、解析器定义、实际解析器等相关文件较多,因此在进行更改时需要修改多个文件,很繁琐

同样,还发现了一些不满点。

在这种情况下,我遇到了一个叫TypeGraphql的东西,我认为通过它可以解决上述的不满,并能进行高效的开发,所以与大家分享一下。

请以中文本地化重新表达以下内容,只需要一种选项:
TypeGraphql官方文档

文 章 更 新 记 录

日付更新内容2021/05/31「4・バリデーションが簡単に実装できる」を追加

TypeGraphql的优点

1.使用装饰器进行直观操作

• 模式定义

在TypeGraphql中,我们可以使用类和装饰器(通过@进行定义)来定义模式,它是Typescript/Javascript的一个功能。

以前我们使用SDL(Schema Definition Language)来定义GraphQL的模式。

// 例:「User」というスキーマを定義
import { gql } from 'apollo-server'

const typeDefs = gql`
type User {
    id: ID!
    userName: String!
    password: String!
}
`

当使用 TypeGraphql 进行架构定义时,代码会变成这样。

// 例: TypeGraphqlを用いて「User」スキーマを定義
import { Field, ObjectType } from 'type-graphql'

@ObjectType()
class User {

    @Field(() => ID)
    id: number;

    @Field(() => String)
    userName: string;

    @Field(() => String)
    password: string;

}

只有这样一来感觉并没有很舒服,但是结合之后提到的ORM,这种描述方法才能展现真正的价值。

・解決者的定义

在定义解析器时,通常首先定义解析器的类型,然后描述实际的处理过程。

import { gql } from 'apollo-server'

const typeDefs = gql`
   type User {
       id: ID!
       userName: String!
       password: String!
   }

// リゾルバーの型定義
   type Query {
       getUsers: [User]!
       getUser(userName: String!): User!
   }
`
// リゾルバーの実装
   const resolvers = {
       Query: {
           //全ユーザーを取得
           getUsers() => {
              //省略 
           }
           //引数(userName)のユーザーを取得
           getUser(_, {userName}) => {
             //省略
           }      
       }
   }

在这种情况下,必须将类型定义和实现分开描述,当进行更改时,经常需要在更改类型定义后再更改实现…这样文件之间来回切换的次数很多,自然也会导致很多错误产生。
在我以前使用这种方法进行开发时,经常会忘记在更改解析器时同时更改其中之一,导致出现错误。

如果在typeGraphql中定义解析器,会发生什么?

import { Args, Query, Resolver } from 'type-graphql'

@Resolver()
  class resolvers {
      //全ユーザーを取得
      @Query(() => User)
      getUsers() {
         //省略
      }
      //引数(userName)のユーザーを取得
      @Query(() => User)
      getUser(@Args('userName') userName: string) {
         //省略
      }
  }

你认为呢?通过装饰器,我们可以将解析器的类型定义和实现合并为一个。通过合并成一个,当需要进行更改时,只需修改一个文件,而且由于Typescript几乎可以事先提醒错误位置,因此大大减少了错误,提高了开发效率。

通过与ORM结合,可以轻松定义模式。

TypeGraphql是与ORM非常兼容的,可以使用诸如Sequalize-typescript、TypeORM、TypeGoose等装饰器来定义实体的ORM库。只需将TypeGraphql的装饰器添加到ORM实体上,即可创建GraphQL的模式定义。

让我们尝试在TypeORM定义的实体中定义TypeGraphQL的模式作为例子。

import { Field, ObjectType } from "type-graphql";
import { Column, Entity } from "typeorm";

@ObjectType()//TypeGraphqlの定義部分
@Entity('users')
export class User extends Entity {

    @Field(() => ID)//TypeGraphqlの定義部分
    @PrimaryGeneratedColumn()
    id: number;

    @Field(() => String)//TypeGraphqlの定義部分
    @Column()
    userName: string;

    @Field(() => String)//TypeGraphqlの定義部分
    @Column()
    password: string;

只需在TypeORM实体上稍微添加一些装饰器,就可以轻松地定义GraphQL模式!
如果在定义GraphQL +数据库的情况下使用ORM,以前必须分别定义ORM实体和在另一个文件中定义GraphQL模式,当有变更时,两者都需要修改… 这样容易产生很多错误,非常麻烦。但是,使用TypeGraphQL,可以在一个文件中管理ORM实体的定义和GraphQL模式的定义,非常方便。

TypeORM的公式文件

3. 可以轻松实现的中间件

在TypeGraphql中,实现中间件也变得非常简单。传统上,常常会使用类似”Graphql-middleware”这样的包来实现中间件。但是在TypeGraphql中,为了实现中间件,已经准备了相应的函数和装饰器,使得实现变得非常简单。

import { MiddlewareFn } from "type-graphql";

export const SampleMiddleware: MiddlewareFn = () => {
  //省略
}

只需在解析器中声明“@UseMiddleware()”,您就可以轻松地使用已定义的中间件。

import { Args, Query, Resolver, UseMiddleware } from 'type-graphql'

@Resolver()
  class resolvers {
      @Query(() => User)
      // ↓デコレータをつけるだけ!
      @UseMiddleware(SampleMiddleware)
      getUsers() {
         //省略
      }
  }

我很容易地实现了中间件!

可以轻松实现验证的验证功能

在安装TypeGraphql时,需要同时安装验证库“class-validator”。只需将该库添加到TypeGraphql中定义的InputType项目中,就可以轻松地对输入项目进行验证。


// 例: class-validatorを用いてInputFieldのバリデーションを行う
import { Field, InputType } from 'type-graphql';
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';

@InputType()
export class CreateUserInput {

    @Field()
    @IsNotEmpty({ message: 'ユーザー名は必須項目です!' })
    @MaxLength(15, { message: '15文字以内に収めて下さい!' })
    userName: string;

    @Field()
    @IsNotEmpty({ message: 'Eメールは必須項目です!' })
    @IsEmail({}, { message: '無効なEメールの形式です!' })
    email: string;

    @Field()
    @IsNotEmpty({ message: 'パスワードは必須項目です!' })
    @MaxLength(15, { message: '15文字以内に収めて下さい!' })
    @MinLength(2, { message: '2文字以上に設定して下さい!' })
    password: string;

    @Field()
    @IsNotEmpty({ message: '確認用パスワードは必須項目です!' })
    @MaxLength(15, { message: '15文字以内に収めて下さい!' })
    confirmPassword: string;

}

在定义Mutation时,为了方便,我们可以在@InputType上附加class-validator的装饰器进行验证。通常情况下,验证是在解析器内定义的,这样解析器内的代码就会混合GraphQL处理和验证,使得代码难以理解。但是,使用TypeGraphQL,我们可以像上面那样简单地在@InputType内实现验证,并且不需要在解析器内包含验证代码,从而使代码更加清晰。您可以参考class-validator官方提供的装饰器。此外,您还可以自定义class-validator装饰器。文章正在编写中…

总结

最近,我觉得使用TypeScript取代JS成为主流,但个人感觉使用TypeGraphql更高效地进行开发。
请尝试使用Typescript + TypeGraphql来实现后端。

广告
将在 10 秒后关闭
bannerAds