Работа со значениями перечисления GraphQL в бизнес-коде

#ruby-on-rails #ruby #enums #graphql #graphql-ruby

#ruby-on-rails #ruby #перечисления #graphql #graphql-ruby

Вопрос:

У меня есть перечисление GraphQL, например:

 class MediaFilterType < Types::BaseEnum
  value "TWITTER", value: :twitter
  value "FACEBOOK", value: :facebook
  value "YOUTUBE", value: :youtube
end
  

И поле, которое получает массив этого типа или nil. На самом деле, когда мы получаем nil, мы должны передать, что мы собираемся использовать все доступные значения в перечислении:

 def dashboard(media_types: nil)
  if media_type.nil?
    # Here is the problem below
    media_types = MediaFilterType.values.values.map(amp;:value)
  end
  ...
  DashboardQuery.new(media_types).call
end
  

Поэтому я должен выполнить эту условную очистку для каждого поля, как и для поля панели инструментов. Ничего особенного, за исключением дублирования. Но я думаю, что это ответственность, которая должна быть внутри запроса (есть сотрудник, который может выполнить эту очистку внутри объекта запроса). Но я думаю, что было бы хуже извлекать значения из типа перечисления GQL внутри бизнес-объекта. На самом деле даже не знаю, должен ли я в любом случае извлекать эти значения перечисления.

Является ли хорошей практикой извлекать значения из типа GQL подобным образом?

  • Если все в порядке, есть другой способ использовать значения перечисления внутри бизнес-объекта, такого как объект запроса или средство дезинфекции, не заставляя их зависеть от типа перечисления GQL? Должен ли я создать перечисление с теми же значениями на моем бизнес-уровне?

Ценю любую помощь.

Ответ №1:

Здесь нет однозначного «правильного» ответа. Проблема в том, что graphql-ruby требует значительного дублирования во многих других случаях — подумайте о своих моделях и типах. Я бы не слишком испугался небольшого дублирования. Однако…

Но я думаю, что было бы хуже извлекать значения из типа перечисления GQL внутри бизнес-объекта

Зависит. Если значения используются только в API и буквально нигде больше, ваша реализация уже настолько хороша, насколько это возможно.

Должен ли я создать перечисление с теми же значениями на моем бизнес-уровне?

Это вариант. Если вы откажетесь от документации для типов перечисления GraphQL, вы можете довольно элегантно избавиться от любого дублирования. Предполагая, что вы добавляете свои медиа-фильтры в виде перечислений в некоторой модели:

 class Dashboard
  enum media_types: [:twitter :facebook :youtube]
end
  

Затем вы можете сделать:

 class MediaFilterType < Types::BaseEnum
  Dashboard.media_types.each { |media_type| value(media_type.upcase, value: media_type.to_sym)}
end
  

И для вашего поля:

 types = media_types || Dashboard.media_types
DashboardQuery.new(media_types).call

  

Ваше перечисление модели теперь служит единственным источником истины.

Однако нередко бывает, что ваш API со временем немного отличается от ваших моделей, поэтому в этом случае действительно нет хорошего способа дублировать хотя бы некоторые вещи. Просто чтобы иметь это в виду.