wheatandcatの開発ブログ

React Nativeで開発しているペペロミア & memoirの技術系記事を投稿してます

gqlgenでネストしたオブジェクトのFieldの引数を取得する方法

概要

招待機能で諸々のGraphQLでネストしたオブジェクトのFieldの引数を受け取りたい場面ができて、実装に迷ったので記事にしました。

実装

招待機能を作成で、マイページの画面では招待のリクエスト数のみが欲しくて、一覧画面では招待のリクエスト情報 + ユーザー情報も欲しい状況が起きたので

f:id:wheatandcat:20210622082711p:plain:w200 f:id:wheatandcat:20210622082714p:plain:w200

で以下みたいなGraphQLのQueryを作成しようと考えました。

query RelationshipRequests($input: InputRelationshipRequests!, $skip: Boolean) {
  relationshipRequests(input: $input) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        followerId
        followedId
        createdAt
        updatedAt
        user(skip: $skip) {
          id
          displayName
          image
        }
      }
      cursor
    }
  }
}

なので、schema.graphqlsには以下のように定義

schema.graphqls

type RelationshipRequests {
  pageInfo: PageInfo!
  edges: [RelationshipRequestEdge!]!
}

input InputRelationshipRequests {
  after: String
  first: Int!
}

type Relationship {
  "ID"
  id: ID!
  "フォローしたユーザーID"
  followerId: String!
  "フォローされたユーザーID"
  followedId: String!
  "作成日時"
  createdAt: Time!
  "更新日時"
  updatedAt: Time!
  "ユーザー情報"
  user(skip: Boolean): User
}

やりたかった定義としては、ここの部分です

  user(skip: Boolean): User

skip = falseの時のみuserデータを取得するような動作にしようと思います。 定義を記載したので、以下のコマンドでgqlgenのコードを生成します。

$ go run github.com/99designs/gqlgen generate

↓が生成されたコードです。

■ schema.resolvers.go

func (r *queryResolver) RelationshipRequests(ctx context.Context, input model.InputRelationshipRequests) (*model.RelationshipRequests, error) {
  panic(fmt.Errorf("not implemented"))
}

見るとわかりますが、生成されたコードからはネストしたオブジェクトのFieldの引数であるskipは取得できません。 なので、graphql.GetOperationContextを使用して取得します。

func (r *queryResolver) RelationshipRequests(ctx context.Context, input model.InputRelationshipRequests) (*model.RelationshipRequests, error) {
    userSkip := true // デフォルトをskipにしたいのでtrue

    octx := graphql.GetOperationContext(ctx)
    switch skip := octx.Variables["skip"].(type) {
    case bool:
        userSkip = skip
    }

上記の記述ではネストしたオブジェクトのFieldの引数を取得できました。 機能としては、こちらで問題無く動作しましたが、

取得方法が若干気持ち悪い気がするので、もし他の取得方法が見つけたら改めて記事にしようと思います。