🔖

prisma-nestjs-graphqlで簡単型生成

2022/04/29に公開

初めに

最近、バックエンドの開発でNest.js x GraphQLの構成で開発することが増えてきた。
その時、ちょっと面倒臭いと思うのがDBに新しくテーブルを作ったときやテーブルを更新した時に、わざわざObjectTypeやInputTypeを更新する必要があること。

ここらへんを何とか型生成でサクッと済ませられないものか、、、
と思い、いろいろ調べていたところ何やらNest.js x GraphQL x Prismaで良さげな型生成のパッケージを発見

https://www.npmjs.com/package/prisma-nestjs-graphql

幸い、使用しているORMもPrismaだったので、これは来たと思い試しに使ってみました。

使用方法

使用方法は簡単で、Prismaのschemaファイルにgeneratorなどを書くだけ
もっと凝ろうと思えば、ValidationPipeを追加してValidationなども設定できるっぽい
今回は最小構成で試してみる

ステップは大きく2つ

  • generatorの追加
  • modelの作成

まずは、schema.prismaにgeneratorを追加

schema.prisma
generator nestgraphql {
  provider = "node node_modules/prisma-nestjs-graphql"
  output   = "../src/@generated/prisma-nestjs-graphql"
}

outputで生成先のフォルダをschema.prismaからの相対パスで指定できる

次に、モデルを作成する

schema.prisma
model User {
  id       String @id @default(uuid())
  /// @HideField()
  password String
  name     String
  email    String
}

この際///(3つのスラッシュ)からはじまるコメントでディレクティブを記述することで生成されるObjectTypeやInputTypeにディレクティブを追加することができる

今回 password の上に @HideField() のディレクティブを追加している
これを追加することで対象のフィールドをGraphQLのスキーマから除外することができる
今回でいうと password は外に出てほしくない情報なので、 @HideField() を追加することで秘匿化している

また、 @HideField({ input: true, output: true }) とすると、入力側からも出力側からも除外される
(例えば、createdAtなどアプリ上必要ない情報はこうやって隠すといいかも?)

ちなみにデフォルトの @HideField()@HideField({ output: true }) と同じ

生成された型

実際に生成されたファイルがこちら

@HideField() で指定したものがちゃんとディレクティブでついていることがわかる
prismaのスキーマで何もコメントを追加していないとデフォルトで良きに型をつけてField化してくれる

user.model.ts
@ObjectType()
export class User {

    @Field(() => ID, {nullable:false})
    id!: string;

    @HideField()
    password!: string;

    @Field(() => String, {nullable:false})
    name!: string;

    @Field(() => String, {nullable:false})
    email!: string;
}

続いてInputType
こちらもちゃんと型が生成されている
今回passwordは出力だけ隠すようにしたのでInputTypeはFieldとして定義されている

user-create.input.ts
@InputType()
export class UserCreateInput {

    @Field(() => String, {nullable:true})
    id?: string;

    @Field(() => String, {nullable:false})
    password!: string;

    @Field(() => String, {nullable:false})
    name!: string;

    @Field(() => String, {nullable:false})
    email!: string;
}

最後にArgsType
こちららは先ほどのInputTypeを持つArgsになっている
Resolverではこの型を貰えば、そのままPrismaでcreateできるようになっている

create-one-user.args.ts
@ArgsType()
export class CreateOneUserArgs {

    @Field(() => UserCreateInput, {nullable:false})
    data!: UserCreateInput;
}

最後に

今回、prisma-nestjs-graphqlを使用し型生成を行なってみたが、割とたくさんファイルが生成されており、色んなユースケースに対して使用できそうな感じだった
(ここでは3つの型しか紹介していないが、みた感じ30~40ファイルくらい生成されている)

シンプルなCRUDアプリならかなり強力な型生成だと思う。
一方、ちょっと複雑さがあるようなアプリだとどうなるのかがまだ不明なので、引き続き使ってみて実用化可能かどうかを判断してみないなと思います

とりあえず、Validationは便利そうなので使ってみたい

Discussion