Типы перечисления GraphQL SDL



У нас есть куча типов перечисления, определенных в SDL, и они отлично работают для запросов и мутаций.
В разделе решатели они сопоставляются со строками, которые представляют эти перечисления в задней части.



Например, в SDL мы имеем:



enum WRRole {
USER
PROVIDER
SUPPORT
ADMIN
SUPER_ADMIN
GUEST
}


А в разделе решатели мы имеем:



WRRole: {
USER: 'user',
PROVIDER: 'provider',
SUPPORT: 'support',
ADMIN: 'admin',
SUPER_ADMIN: 'super admin',
GUEST: 'guest'
},


Преобразователи соответствуют значениям enum, определенным в серверной части nodejs с использованием Мангуста, где поле определяется как:



...
roles: {
type: [
{
type: String,
enum: ['user', 'provider', 'support', 'admin', 'super admin', 'guest']
}
],
default: ['user']
},
...


Проблема, которую мы имеем с перечислениями GraphQL, заключается в следующем что мы не можем проверить перечисления и вернуться сопоставления, используя GraphQL самоанализа....



Это вызывает проблемы с построением пользовательского интерфейса, где мы хотим представить пользователю выпадающий список этих параметров. Значения перечисления SDL, такие как SUPER_USER, отлично подходят для ключей, но мы хотим отобразить фактическое значение backend, сопоставленное с использованием для выбора.



Это только один пример из многих перечислений, которые у нас есть. Многие из отображенных значений состоят из нескольких слов, которые имеют пробелы между или слова, содержащие символы, не разрешенные в значении перечисления SDL, такие как" super admin " в этом случае.

Таков мой вопрос... Как вы все справляетесь с такими вещами, не повторяясь и не добавляя больше кода на передний план, чтобы сопоставить их с более полезными значимыми именами для презентации ????



Нельзя гарантировать, что порядок будет соответствовать определенному порядку перечислений в бэкэнде, поэтому добавление перечислений в бэкэнд-модель серьезно испортит любые предположения, что SUPER_USER на самом деле сопоставляется с "суперпользователем", хотя решатель это знает.



С уважением



Стив

583   1  

1 ответ:

Пока нет идеального решения для этого ИМХО есть несколько способов, которыми я бы подошел к этой проблеме

  1. элегантный способ
    Вы можете добавить в свою схему graphql запрос, который получает имя Enum вот так (в SDL ) :

    type Query {
         getEnumValues(enumName: String!): [EnumKeyValue!]!
    }
    
    type EnumKeyValue {
         key: String!
         value: String
    }
    

    Это требует, чтобы вы немного изменили свой бэкенд-код, например, я бы изменил Enum решатель, чтобы получить его данные из объекта, например:

    const enums = {
        WRRole: {
            USER: 'user',
            PROVIDER: 'provider',
            ...
        }
    };
    
    const enumResolver = {
        WRRole: {
           USER: enums.WRRole.USER,
           PROVIDER: enums.WRRole.PROVIDER,
           ...
        }
    };
    

    А затем решатель для getEnumValues будет выглядеть так:

    const queryResolvers = {
          getEnumValues(source, args) {
               const enumKey = args.enumName;
    
               // enums is the same enums object from the previous example
               return Object.keys(enums[enumKey]).map(key => ({ 
                    key,
                    value: enums[enumKey][key] 
               }))
    
          }
    };
    


  2. грязный, оскорбительный, но быстрый
    Другой возможный способ, который немного оскорбителен, - это добавить описание к значению Enum. так что ваш Enum SDL хотелось бы:

        enum WRRole {
          # user
          USER
          # provider
          PROVIDER
          # support
          SUPPORT
          # admin
          ADMIN
          # super admin
          SUPER_ADMIN
          # guest
          GUEST
        }
    

    А затем вы можете получить отображение между ключом и описанием с помощью следующего запроса:

        {
          __type(name: "WRRole") {
            enumValues {
              description
              name
            }
          }
        }
    

Comments

    Ничего не найдено.