Оператор GraphQL `in` не работает при использовании статического веб-приложения Azure

Я использую Статическое веб-приложение Azure с базой данных SQL Azure. При фильтрации данных я хочу использовать оператор in вместо оператора eq. Пока что оператор eq работает как положено:

async function filterProducts() {
  const query = `
    query Products {
      products(filter: { category: { eq: "dairy" } }) {
        items {
          date
          category
          price
        }
      }
    }`;
  
  const filteredProducts = await fetch('/data-api/graphql', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: query })
  })
    .then((response) => response.json())
    .then((dataJson) => {
      const dataItems = dataJson.data.products.items;
      const dates = dataItems.map((product) => product.date);
      const prices = dataItems.map((product) => product.price);
      return { dates, prices };
    })
    .catch((err) => console.warn('Unable to fetch from the endpoint.', err));

  return filteredProducts;
}

Однако использование оператора in приведет к ошибке статуса 400 (неверный запрос). Это входной запрос:

  const query = `
    query Products {
      products(filter: { category: { in: ["dairy", "fruit"] } }) {
        items {
          date
          category
          price
        }
      }
    }`;

И я получил ошибку при вызове конечной точки localhost:4280/data-api/graphql:

Не удалось загрузить ресурс: сервер ответил со статусом 400 (неверный запрос).

Можно ли использовать оператор in из статического веб-приложения Azure? Как отфильтровать несколько значений с помощью GraphQL в статическом веб-приложении Azure?

используют GraphQL и Gatsby

Sampath 17.04.2024 12:52

@Sampath Я не использую пакет gatsby. Я использую только строку запроса и отправляю ее в GraphQL API, который генерируется с помощью инструмента Azure Static Web App CLI.

Péter Szilvási 17.04.2024 13:26

какой инструмент вы использовали

Sampath 17.04.2024 13:29

@Sampath Я создал приложение Svelte.

Péter Szilvási 17.04.2024 13:31
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
0
4
83
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Последний API REST Graph поддерживает $filter с условием. Пример URL-адреса для него будет выглядеть как ~/users?$filter=mail in ('[email protected]', '[email protected]'). Надеюсь, вы сможете попробовать ("dairy", "fruit") вместо ["молочные", "фруктовые"].

Рекомендации

Graph API — используйте параметр запроса фильтра

К сожалению, замена фильтра на ("dairy", "fruit") не работает. Он возвращается с той же ошибкой. Я проверил схему GraphQL с помощью Postman, и она не содержит оператора in.

Péter Szilvási 17.04.2024 11:06

@PéterSzilvási Я попробовал этот образец lucasconstantino.github.io/graphiql-online, и он сработал нормально. запрос стран { страны (фильтр: { имя: { in: ["Андорра", "Объединенные Арабские Эмираты"] } }) {имя } } Можете ли вы проверить, что вы получаете в err ? Я бы сказал, что запрос GraphQL выглядит нормально.

Srinivasan Jayakumar 17.04.2024 13:06

Я думаю, что существует ограничение на сервере GraphQL статического веб-приложения Azure.

Péter Szilvási 17.04.2024 13:20

После запуска статического веб-приложения (SWA) я исследовал схему GraphQL с помощью Postman. Поскольку я использую интерфейсную платформу Svelte, сервер разработки прослушивает порт 5000. Поэтому я указал http://localhost:5000/graphql в URL-адресе, перешел на вкладку «Схема» и загрузил схему с помощью «Использование самоанализа GraphQL». Вернувшись на вкладку «Запрос», я могу выполнить поиск по доступным параметрам фильтрации:

Что касается API GraphQL статического веб-приложения, я не вижу параметров фильтрации in. Можно проверить равенство, содержащее или начинающееся с условий, используя ввод одной строки.

Учитывая это ограничение, я реализовал обходной путь, используя список категорий с циклом for и параметр фильтрации eq:

async function filterProducts() {
  let result = [];
  const categories = ['dairy', 'fruit'];
  for (const category of categories) {
    const query = `
      query Products {
        products(filter: { category: { eq: "${category}" } }) {
          items {
            date
            category
            price
          }
        }
      }`;

    const filteredProducts = await fetch('/data-api/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query: query })
    })
      .then((response) => response.json())
      .then((dataJson) => {
        const dataItems = dataJson.data.products.items;
        const dates = dataItems.map((product) => product.date);
        const prices = dataItems.map((product) => product.price);
        return { dates, prices };
      })
      .catch((err) => console.warn('Unable to fetch from the endpoint.', err));

    result = result.concat(filteredProducts);
  }

  return result;
}

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

Примечание. Было бы неплохо использовать оператор in, но, поскольку у SWA есть свои ограничения, я думаю, «нам придется готовить из того, что есть».

Обновлено: Будьте осторожны, потому что API GraphQL (а также REST) ​​извлекает данные в пакетном режиме. Размер пакета по умолчанию — 100, поэтому для получения всех данных необходим метод пагинации.

Ответ принят как подходящий

Ответ https://stackoverflow.com/a/78345944/10721627 является неполным, поскольку по умолчанию он извлекает только 100 данных. Чтобы собрать все данные, нам нужно использовать hasNextPage в качестве оператора возврата и переназначать afterCursor переменной endCursor на каждой итерации.

async function filterProducts() {
  let allProducts = [];
  let pageSize = 1000;
  let hasNextPage = true;
  let afterCursor = null;

  // Fetches all data from the endpoint using pagination.
  while (hasNextPage) {
    const query = `
      query Products {
        products(first: ${pageSize}, after: ${afterCursor}) {
          items {
            date
            category
            price
          }
          hasNextPage
          endCursor
        }
      }
      `;

    await fetch('/data-api/graphql', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ query: query })
    })
      .then((response) => response.json())
      .then((dataJson) => {
        allProducts = allProducts.concat(dataJson.data.products.items);

        hasNextPage = dataJson.data.products.hasNextPage;
        afterCursor = `"${dataJson.data.products.endCursor}"`;
      })
      .catch((err) => {
        console.warn('Unable to fetch the data from the `selectAllMaterialStock` endpoint.', err);
        hasNextPage = false;
      });
  }

  // Filters the data using the fields.
  const categories = ['dairy', 'fruits'];
  const filteredProducts = allProducts.filter((item) => categories.includes(item.category));

  return filteredProducts;
}

Мы добавляем полученные данные в массив allProducts. Получив полные данные, мы можем отфильтровать их с помощью встроенного метода Array.prototype.filter(), поскольку оператор in использовать нельзя, см. предыдущий ответ.

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

Другие вопросы по теме

Похожие вопросы

Максимальное количество запусков ожидания приложения Azure Logic App. Что произойдет, если лимит будет превышен?
Ошибка приложения в веб-службе Azure после развертывания API Node.js с помощью Azure DevOps
Локальному приложению-демону не удается вызвать защищенный API ASP.Net Core (ошибка 403)
Служба связи Azure для видеовызова — входящий вызов от/к одновременно
Как извлечь имя параметра среды выполнения из Azure Devops? Я хочу извлечь имя веб-перехватчика, который запустил конвейер?
Установите путь выходных данных задания AzureML к рабочему каталогу
Как получить значение столбца из сложного json при создании конвейера ADF
Уведомления FCM V1 не доставляются из Центра уведомлений Azure
Извлечение информации о разрешениях из отчета о разрешениях, созданного в результате вызова DevOps API в PowerShell
Передача пользовательского идентификатора отслеживания из приложения Logic в приложение Function