Рубрики
Без рубрики

Написание резолюров GraphQL

Узнайте, как писать более сложные резолюры с помощью пользовательских типов. Tagged with GraphQL, JavaScript.

Я работаю и пишу API GraphQL уже пару месяцев, и я чувствую, что получил хорошее понимание оснований. Я пытался углубиться в GraphQL, и один из предметов, которые привели меня к этому, – это более сложные вопросы и резолюры. Вы можете взять те же принципы, о которых я буду говорить, и применить их к мутациям, но я не буду сосредотачиваться на них в данный момент. Мои примеры будут основаны на использовании Apollo Server, поэтому, если код выглядит иначе, чем фреймворк, к которой вы привыкли, я прошу прощения. До сих пор я успешно написал несколько практических вложенных запросов, и я рад увидеть, что еще я могу сделать с этой концепцией. Я хотел написать и поделиться немного больше о моем понимании по этой теме. Я написал маленький сервер, который реализует то, о чем я буду говорить, поэтому не стесняйтесь следить за Анкет

Есть Основной пример вложенного запроса на сайте Apollo Server о получении книг, которые написал автор. Я думаю, что это хороший пример, но не обязательно лучшее объяснение того, как работают вложенные резолюры или могут использоваться. На мой взгляд, знание по предмету не имеет большого значения, если вы не знаете, как применять это знание. Широкое приложение к знанию, которое связанная выше документация пытается показать, состоит в том, что вы можете гнездо что угодно в своей схеме, которая не заканчивается в скаляре. Это означает, что любой Тип Вы добавляете в свою схему потенциально иметь свой собственный резолей. Имея это в виду, попробуйте спроектировать свою схему для повторного использования, пытаясь использовать общие типы и соответствующим образом гнездовать. Если вы не заботитесь о написании вложенного резолей, вы также можете воспользоваться резолюрующими средствами по умолчанию на сервере Apollo. Позже я мог бы написать еще один пост о резоклетеле по умолчанию, но сейчас мы можем продолжить обсуждение вложенных резолюров. Я использую термин «вложенный резолвер» для любого разрешения, который не является Запрос или Мутация (Резерверы корней). Если у вас есть Тип автор Как пример из документации Apollo Server, связанного выше, вы можете сделать решатель для Автор Это разрешает все книги, которые написал автор. Эти данные могут поступать из DB, другого API или где -либо еще. Удивительное преимущество этого заключается в том, что у вас могут быть разные источники данных, которые вносят вклад только тогда, когда их запрашивают клиент.

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

const typeDefs = gql`
  type Person {
    name: String
    awards: [String]
  }

  type College {
    name: String
    dean: Person
    notableGraduates: [String]
    numberOfStudents: Int
  }

  type Cost {
    tuition: Float
    costOfLiving: Float
    averageBooks: Float
    averageFinancialAid: Float
  }

  type University {
    colleges: [College]
    cost: Cost
  }

  type Query {
    university(name: String): University
  }
`;

В этом примере есть несколько разных типов тип S бегает. Есть корень типа: Запрос ; Типы, состоящие из скалярных скал: по умолчанию: Стоимость и Человек ; Тип, изготовленный из других типов: Университет ; и тип, изготовленный из скаляров и типов: Колледж Анкет

Если вы занимались сервером GraphQL и Apollo, то вы, вероятно, уже знаете, как написать резольвер для Запрос Это возвращает скаляр. Возвращение для определения, который вы определяете, не сильно отличается; Вы просто возвращаете объект с соответствующими ключами. Возможно, запутанная часть написания вложенных резокриверов использует родитель Анкет По крайней мере, это то, что называет Apollo Server. Как только родительский резольвер возвращается, у ребенка/вложенного Resolver может использовать возвращенные данные. Так что, если мы посмотрим на Тип университета , вероятно, мы можем видеть, что нам понадобится способ разрешить стоимость и разные колледжи, которые составляют университет, основываясь на названии, которое передается. Пример резолюра для Запрос S Университет может быть:

const resolvers = {
  Query: {
    university: (parent, args, context, info) => ({ name: args.name }),
  },
};

Это позволяет использовать входные резолюры, поскольку мы возвращаем одну и ту же информацию только в другом формате. Примечание. Это так же действительно передавать вход непосредственно вниз, как и следующее:

const resolvers = {
  Query: {
    university: (parent, args, context, info) => args,
  },
};

Я передаю возврат родителей в качестве объекта с ключевым именем для этого первого резолятора, чтобы показать, что существуют разные способы возврата и доступа к родительской информации. В некоторых других примерах я верну родителя как единое значение, а не объект. Причина, по которой я передал вклад детям, заключалась в том, что оба вложенных резолюра, которые нам нужно написать для Университет Тип должен будет знать название университета. Чтобы захватить возвращаемое значение от родителя, мы используем первый аргумент, переданный в резольвер (я буду называть его Родитель ).

Далее приходит пример Стоимость Resolver (это будет добавлено в Resolver Объект, который я начал в последнем фрагменте кода).

  University: {
    cost: (parent, args, context, info) => {
      const costInfo = getCostInfo(parent.name);
      /**
       * Expects returned format:
       * {
       *    tuition: float
       *    costOfLiving: float
       *    averageBooks: float
       *    averageFinancialAid: float
       * }
       */
      return costInfo;
    },
  },

Мы можем предположить, что GetCostinfo Вытаскивает данные из любого источника (ов), которые ему нужно, и возвращает правильный формат. Эта ветвь Ресооформирование дерева теперь завершено, так как мы вернули скаляры. Я думаю, что это хороший момент остановки для большего объяснения. Если вы никогда раньше не писали резольвер для вложенного запроса, это может показаться странным. По крайней мере, это сделало со мной в первый раз, когда я написал один и сделал шаг назад. Мы написали решатель для Тип университета а не Запрос . Через несколько секунд это имеет смысл, хотя. Если вы можете сделать то же самое для Запрос , почему не для создания типа, который мы создали? Вы могли бы даже сломать Стоимость Резолюру больше и потяните данные для отдельных полей из разных источников. Пока каждое поле, которое заканчивается в скатаре, разрешено на этом уровне, вы должны быть полезны. Вам разрешено форматировать возврат в качестве объекта (используя резолюры по умолчанию) или вернуть отдельные значения. В Стоимость Например, я форматирую возвращенный объект для этого резолюра в соответствии с определением схемы. В резолюрах для типа Колледж Я верну отдельные значения вместо форматированного объекта, чтобы показать другой вариант.

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

  University: {
    colleges: (parent, args, context, info) => {
      const colleges = getColleges(parent.name);
      return colleges;
    },
  },

Этот пример выглядит слишком просто, чтобы быть правильным, но просто подождите. колледжи Resolver находит название колледжей в университете и просто возвращает их. Есть некоторые предположения и Givens, которые должны быть на месте для того, чтобы выработать для дальнейших вложенных резолюров. Первый, который я делаю, это то, что GetColleges возвращает массив. Второе предположение состоит в том, что есть и другие резолюры для Колледж тип. В этом и будущем примерах в этом посте я собираюсь предположить, что GetColleges Возвращает множество струн.

Вот оставшиеся резолюры для Колледж :

  College: {
    name: (parent, args, context, info) => {
      return parent;
    },
    dean: (parent, args, context, info) => {
      return getDean(parent);
    },
    notableGraduates: (parent, args, context, info) => {
      return getNotableGraduates(parent);
    },
    numberOfStudents: (parent, args, context, info) => {
      return getNumberOfStudents(parent);
    },
  },

Чтобы дополнительно объяснить странно простое возвратное значение для University.colleges Я подумал, что было бы полезно показать Колледж Резерверы в первую очередь. Эти резолюры выглядят так, как будто они используют одно значение для родитель хотя University.collegesgetColleges ) вернул массив струн. Это связано с тем, что Apollo Server вызывает вложенные резолюры один раз на запись в массиве, и значение родитель это значение для конкретного индекса в этом массиве. Это означает, что для более сложной схемы и резолюров, которые нуждаются в дополнительной информации, вы можете попросить родителя вернуть массив объектов с любой информацией, которую нуждается в вложенных решателях. Мне нравится думать об этом как о сервере Apollo, занимаясь .для каждого () По возвращению родителя. Это что -то особенное и интересное для резоклеров, которые являются массивами, такими как University.colleges Анкет Мне было трудно понять это, когда я впервые столкнулся с этим, но очень мощный, когда я понял это. Также вы можете увидеть, колледжи Значения, которые заканчиваются скалярным ( Примечания. и число учреждений ) просто решаются самостоятельно и возвращаются в Колледж тип.

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

  Person: {
    name: (parent, args, context, info) => {
      return parent;
    },
    awards: (parent, args, context, info) => {
      const awards = getAwards(parent);
      return awards;
    },
  },

Пока вы следили за этим, это не должно быть удивлением.

Я думаю, что в этом материале интересно, и я сделал это немного сложнее, чем должно было быть нарочно. Если вы можете понять, что здесь происходит, я уверен, что вы можете найти резолюры для своего собственного проекта. Удачи!

Оригинал: “https://dev.to/thomasstep/writing-graphql-resolvers-4bj9”