Как определить явный тип, возвращаемый запросом к типу интерфейса GraphQL? - PullRequest
0 голосов
/ 08 февраля 2020

Скажем, у нас есть эта схема GraphQL, которая использует наследование:

Query {
  maintenanceEvents: [MaintenanceEvent]!
}

interface MaintenaceEvent {
  time: DateTime
}

type OilChange implements MaintenanceEvent {
  time: DateTime
  oilType: OilType
}

type TireRotation implements MaintenanceEvent {
  time: DateTime
  pattern: RotationPattern
}

... more types

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

Некоторые варианты, которые я предложил:

  1. Добавить поле типа в интерфейс и для каждого реализующего его типа.

    Это выглядит так:

    enum MaintenanceEventType {
      OIL_CHANGE
      TIRE_ROTATION
      ... more types
    }
    
    interface MaintenanceEvent {
      time: DateTime
      type: MaintenanceEventType
    }
    
    type OilChange implements MaintenanceEvent {
      time: DateTime
      type: MaintenanceEventType
      oilType: OilType
    }
    
    ...etc.
    

    Это это лучший вариант, который я придумала, но есть вещи, которые мне не нравятся. Существует два списка поддерживаемых типов событий обслуживания, которые нужно синхронизировать c: перечисление и набор интерфейсов. Кроме того, представляется избыточным отправлять поле, которое всегда одинаково для данного типа.

  2. Определить тип во внешнем интерфейсе на основе имеющихся полей.

    Это не хороший вариант. Он подвержен ошибкам, и логика c определяет, какой тип будет изменен, если поля будут добавлены к типам. Кроме того, он не может обрабатывать типы, которые реализуют интерфейс, но не имеют дополнительных полей.

Существует ли установленный шаблон для этого или часть спецификации GraphQL, которая занимается этим? Разве это не хорошее применение интерфейсов GraphQL?

1 Ответ

1 голос
/ 08 февраля 2020

Вы должны использовать поле __typename. Из spe c:

GraphQL поддерживает интроспекцию имени типа в любой точке запроса с помощью метаполя __typename: String! при запросе любого объекта, интерфейса или объединения. Возвращает имя типа объекта, запрашиваемого в данный момент.

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

Это Поле неявно и не отображается в списке полей ни в одном из определенных типов.

Ваш запрос будет выглядеть примерно так:

query {
  maintenanceEvents {
    __typename
    time
    ... on OilChange {
      oilType
    }
    ... on TireRotation {
      pattern
    }
  }
}

Обратите внимание, что если вы используете Apollo Client, Поле __typename будет автоматически добавлено к вашим запросам - в этом случае нет необходимости явно добавлять его самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...