В GraphQL как управлять запросом БД по клиентскому запросу? - PullRequest
0 голосов
/ 05 марта 2019

Я учусь использовать GraphQL в эти дни.На мой взгляд, для построения запроса мне нужно построить три части:

  1. Схема
type User{
  id String
  name String
  cars [Car!]!
}
type Car{
  id String
}
type Query{
  user(id: String): User
}
Функция DB Query
{
  user: async function ({id}) {
    const user = await DB.user.findOne({id});
    const userCars = await DB.car.find({userId: id});
    user.cars = userCars;
    return cars;
  }
}
Клиентский запрос
{
  user (id: "1") {
    name
    cars {
      id
    }
  }
}

Этот запрос возвращает имя пользователя и его автомобили.Функция запроса БД всегда запрос для автомобилей.

Но иногда мне просто нужна информация пользователя:

{
  user (id: "1") {
    name
  }
}

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

Как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

Я думаю, что вы ищете автоматическое создание / отображение из запроса GraphQL в запрос базы данных.

Каждый запрос зависит от базы данных / проекта, поэтому вы должны создать это отображение.Вы можете легко сделать это с помощью пакета graphql-fields .

Из пакета вставлен раздел WHY, скопированный из копии:

Базовый API REST может возвращать только поляна основе параметров запроса.

{
  user {
    profile {
      firstName
    },
    id
  }
}

должен запросить /api/user?fields=profile,id

, а

{
  user {
    email
  }
}

должен запросить /api/user?fields=email Реализуйте свой метод разрешения следующим образом:

resolve(root, args, context, info) {
    const topLevelFields = Object.keys(graphqlFields(info));
    return fetch(`/api/user?fields=${topLevelFields.join(',')}`);
}
0 голосов
/ 05 марта 2019

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

Если вы используете RDS, присоединяйтесь к монстру, и громкость данных может помочь оптимизировать производительность ваших запросов.

  • Join Monster , который опирается на генерацию одного большого запроса на соединение, а также решает проблему запроса только тех полей, которые вам нужны, из БД
  • Кэшированный и пакетный источник данных SQL который использует загрузчик данных Facebook изнутри - он не решит проблему того, какие поля запрашивать (хотя в примере используется knex, что сделает это намного проще), но вместо этого он может кэшировать и группировать ваши запросы
0 голосов
/ 05 марта 2019

GraphQL.js будет поддерживать либо свойства объекта, либо методы для функций распознавателя;это обсуждается на странице Типы объектов .

Один из способов справиться с этим - просто вставить анонимную функцию непосредственно в возвращаемый объект:

{
  user: async function ({id}) {
    const user = await DB.user.findOne({id});
    user.cars = () => DB.car.find({userId: id});
    return cars;
  }
}

Другой способ - создать объект-оболочку с классом, который предоставляет свойство id и (асинхронный, ленивый) метод cars;некоторые примеры этого приведены в документации GraphQL.js .Этот подход имеет тенденцию работать в большинстве реализаций GraphQL на большинстве языков.

...