0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NestJS + prisma + GraphQL でRecordNotFoundを発生させる方法

Last updated at Posted at 2022-04-21

概要

例えば、IDをもとに単一のオブジェクトを取得するqueryで存在しないIDを指定した際、nullとして返すのか404エラーで返すのか迷った。
(404エラーと表現したが、GraphQLではエラーの際、レスポンスステータスとしては200で返し、レスポンスボディにエラーの情報を入れるのが一般的。)
どちらが一般的なのかはよくわかっていないが、nullとして返すとフロントエンドでのハンドリングに一貫性がなくなりそうだったので、404エラーとして返す方法を試してみた。

結論

rejectOnNotFound optionを使用し、NestJSの NotFoundException を発生させるようにした。

prisma.service.ts
import { INestApplication, Injectable, OnModuleInit, NotFoundException } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  constructor() {
    super({
      log: ["query"],
      rejectOnNotFound: () => new NotFoundException(),
    });
  }

  async onModuleInit() {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on("beforeExit", async () => {
      await app.close();
    });
  }
}

私はApolloDriverを使っているが、存在しないIDにアクセスしようとした際、以下のように返してくれる。完璧だ。
スクリーンショット 0004-04-21 19.06.37.png

ボツ案1

return await this.prismaService.findUnique.findUnique(id) | new NotFoundException();

流石に安直すぎるか?となって却下。
構成によってはresolverとprismaを直接依存させたくないために、間にserviceをかませている場合もあると思うし、そうなるといちいち間にかませているserviceごとに書くことになって面倒というのもある。

ボツ案2

rejectOnNotFound: true を指定

https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#rejectonnotfound を見ると true/false を指定でき、trueにするとデフォルトで NotFoundError なるものを返してくれる。
これもいちいちcatchしてNestJSのNotFoundExceptionを投げ直すのが面倒なので却下。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?