Должен ли я ожидать, что типы перечислений будут разрешаться автоматически, или типы существуют только для ограничения параметров?
Учитывая следующую схему GraphQL:
type Job {
description: String!
status: Status!
}
enum Status {
PENDING_REVIEW
PENDING_APPROVAL
APPROVED
}
и запрос, который выглядит так:
query job {
description
status
}
Если бы моя база данных вернула следующее:
{ "description": "Some irrelevant job description", "status": 1 }
Я ожидаю, что GraphQL вернется:
{ "description": "Some irrelevant job description", "status": "PENDING_APPROVAL" }
Я что-то неправильно настроил, или это ожидаемое поведение, которое потребует от меня написания преобразователя для status?
const getQuestionStatus = ({ status }) => ['PENDING_REVIEW', 'PENDING_APPROVAL', 'APPROVED'][status];


Я думаю, вам нужно реализовать резольвер для него.
Однако, если вы используете Apollo Server, у него есть функция Внутренние ценности, где вы можете использовать 1 в качестве внутреннего значения в распознавателе, Apollo Server автоматически сопоставит его с PENDING_APPROVAL при возврате ответа.
Это зависит от языка, на котором вы реализуете GraphQL. Типы перечислений в GraphQL — это типы перечислений просто и ничего более. Это означает, например, что ваш тип перечисления APPROVED ничего не оценивает. Это дает разработчику больше возможностей делать с ними то, что они хотят. Если вы хотите, чтобы перечисление отображалось в целые числа, вам понадобится преобразователь, как вы описали.
Из Статья о GraphQL по схемам и типам:
Note that GraphQL service implementations in various languages will have their own language-specific way to deal with enums. In languages that support enums as a first-class citizen, the implementation might take advantage of that; in a language like JavaScript with no enum support, these values might be internally mapped to a set of integers.
В GraphQL.js каждое значение перечисления в типе перечисления может иметь связанное с ним значение. Установка этого значения не является обязательной; по умолчанию это строковое представление имени значения. То есть для перечисления типа:
enum ExampleEnum {
FOO
BAR
}
по умолчанию значение FOO будет "FOO". Если вы используете graphql-tools для построения своей схемы (или используете apollo-server, который использует graphql-tools под капотом), мы можем передать значения для типа Enum прямо в наши преобразователи:
const resolvers = {
Query: {
example: () => 11, // field with ExampleEnum type
},
ExampleEnum: {
FOO: 11,
BAR: 23,
},
}
Как только мы это сделали, мы можем вернуть определенное значение в наш преобразователь, и оно будет сериализовано в соответствующее значение Enum. Примечание: то же самое относится и к перечислениям, которые используются в качестве аргументов — если FOO передается в качестве аргумента, распознаватель фактически получит значение 11.
Отсутствие каких-либо значений эквивалентно выполнению:
ExampleEnum: {
FOO: 'FOO',
BAR: 'BAR',
}
Также стоит отметить, что предоставление значений не влияет на то, как значения перечисления отображаются в ответе. Когда результат выполнения сериализуется в JSON, значения перечисления всегда отображаются в виде строковых значений, которые соответствуют именам значений перечисления (например, "FOO" и "BAR" в нашем примере).
А как насчет ванильного GraphQL.js?
Значения для значений перечисления также могут быть предоставлены, если вы определяете свою схему программно. Вот эквивалент приведенного выше примера:
const ExampleEnumType = new GraphQLEnumType({
name: 'ExampleEnum',
values: {
FOO: {
value: 11,
},
BAR: {
value: 23,
},
},
})
Да, вам нужно написать преобразователь из значений перечисления во все, что вам нужно, например. числа согласно документы apollo-server для внутренних значений. Вот как это сделать в TypeScript:
export enum Status {
DRAFT,
PENDING,
APPROVED
}
const typeDefs = gql`
enum Status {
DRAFT
PENDING
APPROVED
}
type Query {
echo(status: Status!): Int!
}
`;
const resolvers = {
Status: {
DRAFT: Status.DRAFT,
PENDING: Status.PENDING,
APPROVED: Status.APPROVED
},
Query: {
echo(_, { status }): String {
console.info(status);
return status;
}
}
};
Вот Песочница кода, показывающая автоматический анализ и возврат перечисления.
Однако обратите внимание, что для значений перечисления по умолчанию, которые являются параметрами запроса, поведение сомнительно — преобразователь может получить значение перечисления в виде строки или undefined.
Как насчет значений перечисления по умолчанию? Мои тесты показали, что распознаватель получает либо перечисление в виде строки, либо
undefined.