如果你使用Typescript + Graphql,那么我推荐使用TypeGraphql
首先
Graphql是我个人非常喜欢并持续使用的技术。
・与TypeScript不太相兼容
・使用ORM时需要定义ORM,还需要定义GraphQL的模式,所以非常麻烦
・模式定义、解析器定义、实际解析器等相关文件较多,因此在进行更改时需要修改多个文件,很繁琐
同样,还发现了一些不满点。
在这种情况下,我遇到了一个叫TypeGraphql的东西,我认为通过它可以解决上述的不满,并能进行高效的开发,所以与大家分享一下。
请以中文本地化重新表达以下内容,只需要一种选项:
TypeGraphql官方文档
文 章 更 新 记 录
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来实现后端。