Как мне добавить рекурсивную логику в преобразователи с использованием мутаций GraphQL?

#graphql #sequelize.js #apollo-server

#graphql #sequelize.js #apollo-сервер

Вопрос:

Можно ли добавить логику в преобразователи с использованием мутаций GraphQL?

Я пытаюсь создать четырехзначную строку в качестве псевдонима для сообщения, если пользователь ее не предоставляет. Затем я хотел бы проверить базу данных, чтобы увидеть, существует ли четырехзначная строка. Если строка существует, я хотел бы рекурсивно создать еще одну четырехзначную строку.

На данный момент я изучаю добавление логики к мутациям в преобразователях, но я не уверен, выполнимо ли это. Я использую эти документы для своего фонда: graphql.org sequelize.org

Это мой текущий блок кода:

Работает с 12/4/2020

 const MakeSlug = require("./services/MakeSlug");

const resolvers = {
  Query: {
    async allLinks(root, args, { models }) {
      return models.Link.findAll();
    },
    async link(root, { id }, { models }) {
      return models.Link.findByPk(id);
    }
  },
  Mutation: {
    async createLink(root, { slug, description, link }, { models }) {
      if (slug !== undefined) {
        const foundSlug = await models.Link.findOne({
          where: { slug: slug }
        });
        if (foundSlug === undefined) {
          return await models.Link.create({
            slug,
            description,
            link,
            shortLink: `https://shink.com/${slug}`
          });
        } else {
          throw new Error(slug   " exists. Try a new short description.");
        }
      }

      if (slug === undefined) {
        const MAX_ATTEMPTS = 10;
        let attempts = 0;
        while (attempts < MAX_ATTEMPTS) {
          attempts  ;
          let madeSlug = MakeSlug(4);
          const foundSlug = await models.Link.findOne({
            where: { slug: madeSlug }
          });
          if (foundSlug !== undefined) {
            return await models.Link.create({
              slug: madeSlug,
              description,
              link,
              shortLink: `https://shink.com/${madeSlug}`
            });
          }
        }
        throw new Error("Unable to generate unique alias.");
      }
    }
  }
};

module.exports = resolvers;

 

Это моя полная кодовая база.

Спасибо!

Комментарии:

1. нет необходимости в рекурсивном… сделайте … пока?

2. @xadm — Спасибо за отзыв. Я заменил рекурсию циклом while. На данный момент он не работает должным образом, но все работает.

3. Это звучит ужасно фундаментально и ставит ваш предел до 9999 на пользователя или даже хуже, если вы используете идентификатор post для всех пользователей. Если возможно, я думаю, вам следует просто создать еще одну таблицу для post и просто использовать уникальный идентификатор, начинающийся с 1 для post, и вам не нужно беспокоиться о uid, просто вставьте новый post в таблицу

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

5. @peyo тогда вы должны просто создать таблицу post, используя unique identifier и начиная с 1000, в противном случае ваше решение для решения вышеуказанного вопроса всегда будет включать pseudo (без sudo) бесконечную рекурсию, когда число больше. Даже небольшое количество существующих идентификаторов с неудачей может вызвать проблемы. Я настоятельно рекомендую вам не делать этого, если это для реального производства. Для личного удовольствия вы определенно можете попробовать.

Ответ №1:

Цикл while решил проблему. Спасибо xadm.

 const MakeSlug = require("./services/MakeSlug");

const resolvers = {
  Query: {
    async allLinks(root, args, { models }) {
      return models.Link.findAll();
    },
    async link(root, { id }, { models }) {
      return models.Link.findByPk(id);
    }
  },
  Mutation: {
    async createLink(root, { slug, description, link }, { models }) {
      if (slug !== undefined) {
        const foundSlug = await models.Link.findOne({
          where: { slug: slug }
        });
        if (foundSlug === undefined) {
          return await models.Link.create({
            slug,
            description,
            link,
            shortLink: `https://shink.com/${slug}`
          });
        } else {
          throw new Error(slug   " exists. Try a new short description.");
        }
      }

      if (slug === undefined) {
        const MAX_ATTEMPTS = 10;
        let attempts = 0;
        while (attempts < MAX_ATTEMPTS) {
          attempts  ;
          let madeSlug = MakeSlug(4);
          const foundSlug = await models.Link.findOne({
            where: { slug: madeSlug }
          });
          if (foundSlug !== undefined) {
            return await models.Link.create({
              slug: madeSlug,
              description,
              link,
              shortLink: `https://shink.com/${madeSlug}`
            });
          }
        }
        throw new Error("Unable to generate unique alias.");
      }
    }
  }
};

module.exports = resolvers;
 

Комментарии:

1. эх… сделайте { makeslug=MakeSlug(4); найдите … } while (foundSlug!= не определено) … создать ссылку

2. Понятно. Выглядит хорошо. Сохраняя его в соответствии с циклом while. Я внес некоторые изменения в код. Спасибо.

3. эх… найти только в цикле… никаких попыток

4. эх … все еще слишком много while -с … if ( slug if ( foundSlug === null скорее?