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?

GraphQL で実行時に Query と Mutation を判別する方法

Posted at

GraphQL では、Query と Mutation はスキーマ上でははっきり分かれていますが、
「実行時にどちらが呼ばれたのか?」を判別したいケースがあります。

たとえば以下のようなケースが考えられます:

Apollo Server の plugin 内で、リクエストが Query か Mutation かを判定したい

Logging / Tracing / Metrics 用に操作の種類を知りたい

Query だけ rate limit を変えたい、Mutation だけアクセス制御したい など

しかし、GraphQL の実行時コンテキスト(GraphQLResolveInfo など)には
「これは Query/Muation です」と直接分かるプロパティがありません。

解決策:info.operation.operation を使う

GraphQL のリゾルバは、第四引数として GraphQLResolveInfo(info)を受け取ります。

resolve(parent, args, context, info) {
  console.log(info.operation.operation);
}

ここで info.operation.operation には以下の値が入っています:

操作種別	            取得できる値
Query	             "query"
Mutation	        "mutation"
Subscription	  "subscription"

つまり、実行時に これだけでリクエストの種別を判定できるということです。

Apollo Server Plugin での実用例

GraphQL では、

Query は Query 型のフィールド

Mutation は Mutation 型のフィールド
としてスキーマ上に定義されます。

Apollo Server の plugin で実際に判定するには、requestDidStart フックを使います。

const plugin = {
  async requestDidStart() {
    return {
      async executionDidStart(requestContext) {
        const op = requestContext.operation?.operation;
        console.log("Operation type: ", op);
      },
    };
  }
};

ここでも operation.operation を参照するだけで Query/Muation を区別できます。

注意点

GraphQL の クライアントが operation name を省略していても判別可能

Schema の Query / Mutation のフィールドレベルでは区別できない
→ operation(=リクエスト)単位での判定のみ可能

operation はパース直後の AST (OperationDefinitionNode) に基づくため、極めて確実

まとめ

StackOverflow の回答のポイントは以下です:

GraphQL はリクエスト (operation) に対して query / mutation / subscription の情報を保持している

その情報は info.operation.operation または requestContext.operation.operation で取得できる

よって、実行時でも Query と Mutation を安全に区別できる

GraphQL のミドルウェア、ログ、権限管理などで役立つテクニックです。

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?