Типы перечисления 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 на самом деле сопоставляется с "суперпользователем", хотя решатель это знает.
С уважением
Стив
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] })) } };
грязный, оскорбительный, но быстрый
Другой возможный способ, который немного оскорбителен, - это добавить описание к значениюEnum. так что вашEnumSDLхотелось бы:enum WRRole { # user USER # provider PROVIDER # support SUPPORT # admin ADMIN # super admin SUPER_ADMIN # guest GUEST }А затем вы можете получить отображение между ключом и описанием с помощью следующего запроса:
{ __type(name: "WRRole") { enumValues { description name } } }
Comments