Где поля, зависящие от вызывающего, определенные в GraphQL - PullRequest
0 голосов
/ 19 декабря 2018

Я сейчас пишу POC GraphQL-сервер.Однако клиентскому интерфейсу нужны поля, которые являются временными (не являются частью модели БД), и формируются или запрашиваются на лету.Например: A Post может понравиться, поэтому я бы хотел поставить флаг isLiked: Boolean в graphQL.В зависимости от абонента этот флаг будет true, если Post нравится, или false, если нет.Однако это кажется неправильным, так как, строго говоря, оно не является частью Post-типа и является формой UI-связи (то, что мы хотели решить с помощью GraphQL).Также у меня есть ощущение, что мог бы быть лучший способ, обеспечивающий Like в качестве типа (так как он также имеет date, например).Было бы хорошей идеей, чтобы определяемые в вызывающем поле поля определялись в типе, который в основном является подзапросом?

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

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

type User {
  id: ID!
  username: String!
  likedPosts: [Post!]!
  # or better yet
  likedPostIds: [ID!]!
}

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

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

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

0 голосов
/ 19 декабря 2018

GraphQL имеет некоторые ограничения, и я не думаю, что неправильно добавлять поля особых случаев в схему, чтобы обойти эти ограничения, особенно если они представляют какой-то запрос, который какое-то фактическое приложение сделает (и часто).

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

scalar DateTime
interface Node { id: ID! }
type Like implements Node {
  id: ID!
  post: Post!
  date: DateTime!
}
type Post implements Node {
  id: ID!
  title: String!
  date: DateTime!
  likes: [Like!]!
  hasLike: Bool!
}

Если вы этого не сделаете, тогда единственный выбор клиента - запросить конкретные подобные объекты и выбрать из них какое-то поле.Если вы добавите в поле параметры типа лимита, вы сможете минимизировать стоимость, но это все равно будет немного неловко

query PostSummary($id: ID!) {
  node(id: $id) {
    ... on Post {
      title
      date
      likes(limit: 1) { id }
    }
  }
}

Если это реальный вариант использования для вашего приложения, просто добавьте поле hasLikeкажется более разумным API, даже если он несколько «специализирован для пользовательского интерфейса».

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