Как игнорировать неизвестные значения перечисления? - PullRequest
0 голосов
/ 27 апреля 2019

Мне интересно, как лучше всего игнорировать / отбрасывать неизвестные значения перечисления на сервере GraphQL / Apollo.

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

Какой лучший способ сделать это в GraphQL. Моей первой идеей было создать директиву, которая будет считывать поддерживаемые значения из схемы и игнорировать все остальное, но после поиска в поиске я не нашел хороших примеров, как это сделать. Можете ли вы указать мне направление, куда идти об этом?

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

Если ваша функция распознавателя будет принимать произвольные строки, то вы можете использовать пользовательский скалярный тип или просто 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
}

В частности, может не иметь смысла говорить серверу «сделать тип этого объекта игровой площадкой», еслисервер просто не понимает этого.И наоборот, если сервер знает о «игровой площадке», он может вернуть ее в тех случаях, когда клиент может не ожидать.Наличие здесь перечисления делает явным то, о чем знает сервер.Сервер сказал, что он поддерживает, и ответственность за сотрудничество лежит на клиенте.

Обратите внимание, что клиент может выяснить, поддерживает ли сервер игровые площадки, является ли он значением enum, и это может помочь ему проинформировать его.поведение.

query GetServiceTypes {
  __type(name: "Service") {
    enumValues { name }
  }
}
0 голосов
/ 28 апреля 2019

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

Итак, моя первоначальная проблема была вкратце, что я получаю несколько разных «доступных сервисов» из разных сервисов, и я подумывал сопоставить их с enum для лучшей поддержки машинописи и т. Д. Но проблема заключалась в том, что если бы я получить неизвестное значение из другого сервиса, мой 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%, являются ли директивы подходящим вариантом для подобных случаев, но, по крайней мере, это одно из возможных решений.

...