GraphQL ruby でEnumの命名を〇〇_Typeにする
昇降デスクの高さを全く変えない系エンジニアのyosiです。
仕事のレビュー時に調べて特に記事にする予定はなかったのですが、日曜コーディングで再び出くわしたので記事にしておきます。
GraphQLではEnumを定義できて、以下のように書きます。
(ファイルの置き場所を変えてるのでファイルパスとモジュール名は読み替えてください)
class Types::Enums::SortType < Types::BaseEnum
value 'ASC', value: :asc
value 'DESC', value: :desc
end
このEnumは以下のように使えます。
適当なPostTypeが定義してあるものとします。
module Types
class QueryType < Types::BaseObject
# 省略
field :posts, Types::Objects::PostType.connection_type, null: false do
argument :sort, Types::Enums::SortType, required: false, default_value: :desc
end
def posts(sort:)
Post.order(id: sort)
end
end
end
一見これで完了したように思えますが、意図した挙動はしません。
bundle exec rails graphql:schema:json
でGraphQLスキーマファイルを出力してみましょう。
{
"kind": "ENUM",
"name": "Sort",
"description": null,
"interfaces": null,
"possibleTypes": null,
"fields": null,
"inputFields": null,
"enumValues": [
{
"name": "ASC",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DESC",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
]
},
nameがSortになってしまっていて、クラス名につけた_Type
が削除されてしまっています。
Github api v4のenum一覧を見ても_type
とついたEnumはたくさんあるので仕様的にできないということはなさそうです。
Enumの名前をクラス名とは別に設定する
結論としてはgraphql_name
を指定することで実現できます。
class Types::Enums::SortType < Types::BaseEnum
+ graphql_name 'SortType'
+
value 'ASC', value: :asc
value 'DESC', value: :desc
end
bundle exec rails graphql:schema:json
でGraphQLスキーマファイルを再度確認してみると、nameがちゃんとSortType
になってるのが確認できます。
{
"kind": "ENUM",
"name": "SortType",
"description": null,
"interfaces": null,
"possibleTypes": null,
"fields": null,
"inputFields": null,
"enumValues": [
{
"name": "ASC",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DESC",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
]
},
まとめと余談
ドキュメントを読んでもこのあたりへの言及がなくてちょっと困ったのですが、ソースコードを読んでいると/lib/graphql/schema/enum.rb
に以下のようなコメントがありました。
@param graphql_name [String, Symbol] the GraphQL value for this, usually
SCREAMING_CASE
なるほど。
ちなみにSortTypeTypeにすればいいじゃんって一瞬頭によぎったのはあなたと2人だけの秘密です。
Discussion