Cases_Where_Enums_Are_Difficult

GraphQLの大規模リファクタリングでenumが増えたが、「enumだと逆につらいかも?」というケースに遭遇したので、相談も兼ねて共有したい。

数字の選択肢

enum FrequencyMonthEnum {
  """
  6ヶ月
  """
  half_year

  """
  1ヶ月
  """
  month

  """
  3ヶ月
  """
  quarter
}

辛いポイント

  • フロント側で以下の変換を往復する必要がある
    • enum → 対応する数字(昇順に並び替え)→ 対応する日本語(選択肢用)

どのみちフロント側で日本語と対応させる必要がある

  • 検索条件でカテゴリーを指定する時

辛いポイント

  • 結局、選択肢のenumと、対応する日本語で型を用意する必要がある
  • 毎回冗長に書かなければならない
const categoryConditions: { id: CategoryEnum; label: string }[] =
  [
    { id: CategoryEnum.Food, label: 'フード' },
    { id: CategoryEnum.Snack, label: 'スナック' },
    { id: CategoryEnum.Drink, label: 'ドリンク' },
  ]

雑談会で出た話

雑談会で上記を相談したところ、次のような意見をいただけた。

enumではなくオブジェクトの配列で渡すようにする

  • enumだと変更の度にサーバー・フロントの両方を変更しなければならない
  • 例)
type FrequencyMonthCondition {
  conditions: [FrequencyMonth!]!
}

type FrequencyMonth {
  id: ID!
  labelJa: string!
}

"""
以下のように取得できる
[
  { id: 'half_year', labelJa: '6ヶ月'}
  { id: 'month', labelJa: '1ヶ月'}
  { id: 'quater', labelJa: '3ヶ月'}
]
"""

受け渡すデータと対応する、翻訳用データを用意する

  • 「データ上の値」と、「それをどう表示するか」の話なので、多言語対応と似ているかも
  • トップ画面ロード時に各データと対応する翻訳用のデータセットを予め先にフロントに渡す
  • 例)
    • 渡されるデータ
enum FrequencyMonthEnum {
  half_year
  month
  quarter
}
  • 翻訳用データ
type LabelJa {
  frequencyMonth [
    { key: 'half_year', label: '6ヶ月' }
    { key: 'month', label: '1ヶ月' }
    { key: 'quarter', label: '3ヶ月' }
  ]
}