Мне интересно, как лучше всего игнорировать/отбрасывать неизвестные значения перечисления на сервере GraphQL/Apollo.
Допустим, моя схема GraphQL определяет массив перечислений «enum Service {Supermarket, TicketSales}», и сейчас он работает нормально, но позже другой сервис, который я использую, добавляет некоторые новые значения (например, Playground), и мой клиент просто не поддерживает это, и я просто хотел бы игнорировать его и возвращать поддерживаемые значения без ошибок.
Как лучше всего это сделать в GraphQL. Моей первой идеей было создать директиву, которая будет считывать поддерживаемые значения из схемы и игнорировать все остальное, но после поиска в Google я не нашел хороших примеров, как это сделать. Можете ли вы указать мне направление, куда идти по этому поводу?


Если ваша функция распознавателя будет принимать произвольные строки, вы можете использовать собственный скалярный тип или просто String.
"""
The type of a service. `Supermarket` means..., and
`TicketSales` means...; any other value is ignored.
"""
scalar Service
GraphQL обычно возлагает на клиента ответственность за соответствие ожиданиям сервера, а не заставляет сервер пытаться поддерживать любой запрос. Есть несколько мест, где вы можете разумно ожидать появления такого значения перечисления:
enum Service { Supermarket, TicketSales }
type Query {
inAReturnValue: Service!
asAQueryParam(service: Service!): Node
}
type Mutation {
asAMutationInput(service: Service!): Node
}
В частности, может не иметь смысла говорить серверу «сделать тип этого объекта игровой площадкой», если сервер просто этого не понимает. И наоборот, если сервер знает о «детской площадке», он может вернуть ее в случаях, когда клиент может этого не ожидать. Наличие перечисления здесь делает явным то, о чем знает сервер. Сервер сказал, что он поддерживает, и ответственность за сотрудничество лежит на клиенте.
Обратите внимание, что клиент может узнать, поддерживает ли сервер игровые площадки, если это значение перечисления, и это может помочь ему определить свое поведение.
query GetServiceTypes {
__type(name: "Service") {
enumValues { name }
}
}
и данные, с которыми я имею дело, поступают из других служб, поэтому в основном я могу внезапно начать получать некоторые новые значения, о которых я не знал. Поскольку моя схема graphql уже определяет допустимые значения, мне интересно, есть ли простой способ разрешить только их и игнорировать все остальное? Может быть, как-то с пользовательским преобразователем и информационным параметром?
Поиграв, я нашел кое-что, что я могу использовать, чтобы обойти свою первоначальную проблему, поэтому я опубликую это здесь, если кто-то еще задается вопросом о том же.
Итак, моя первоначальная проблема заключалась в том, что я получаю несколько различных строковых массивов типа «доступных служб» от других служб, и я думал сопоставить их с перечислением для лучшей поддержки машинописного текста и т. д. Но проблема заключалась в том, что если я получу какой-то неизвестный значение из другого сервиса, мой graphql не удастся.
Итак, моя первоначальная идея состояла в том, чтобы исправить это с помощью директивы, которую я все-таки заработал:
# In schema
directive @mapUnknownTo(value: String) on ENUM
enum SomeAttribute @mapUnknownTo(value: "__UNKNOWN__") {
SomeAttribute1
AnotherAttribute
SomethingElse
__UNKNOWN__
}
И реализация директивы:
import { SchemaDirectiveVisitor } from 'graphql-tools';
import { GraphQLEnumType } from 'graphql';
export class MapUnknownToDirective extends SchemaDirectiveVisitor {
visitEnum(type: GraphQLEnumType) {
const { value = '__UNKNOWN__' } = this.args;
const valueMap = type.getValues().reduce((map, v) => map.set(v.value, v.name), new Map<string, string>());
type.serialize = (v: string): string => valueMap.get(v) || value;
}
}
Таким образом, это сопоставит все значения, не определенные в схеме, с некоторым пользовательским значением, которое не совсем то, что я изначально хотел, но, по крайней мере, оно не дает ошибки, так что все в порядке.
Я все еще не уверен на 100%, что директивы подходят для таких случаев, но, по крайней мере, это одно из возможных решений.
Спасибо за ваш ответ, есть несколько хороших идей, над которыми мне нужно подумать. В моем случае у нас есть множество различных типов «поддерживаемых служб», которые практически представляют собой массив строк, и причина, по которой я хотел бы сопоставить их с перечислениями, заключается в том, что это прояснит для клиента, какие значения можно ожидать, а не просто случайные строки, и, конечно же, я бы получил для них машинописный текст. Со временем у нас, вероятно, будут представлены некоторые новые службы, которые мы еще не поддерживаем, и, конечно, мой сервер должен каким-то образом отфильтровывать их, пока мы не создадим для них поддержку.