Развертывание Vercel не получит /api во второй раз, оно сохраняет последний запрос get.

Вопрос или проблема

Привет всем, спасибо за прочтение

У меня небольшая проблема с проектом цитат, использующим nextjs, развернутом на Vercel. На локальном компьютере всё работает хорошо, но на развернутом варианте не появляются новые цитаты.

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

Вот мой /api

import axios from "axios";
import { NextResponse } from "next/server";
import { Quotable, QuoteTypes, QuoteZen } from "@/types/quotesType";

const urlWaifu = "https://waifu.it/api/v4/quote";
const urlZen = "https://zenquotes.io/api/random/";
const urlQuotable =
  "https://api.quotable.io/quotes/random?limit=1&tags=technology|famous-quotes|film|love|pain|sadness|self-help";

const list = ["Zen", "Waifu", "Quotable"];
const randomizer = Math.floor(Math.random() * list.length);
const selected = list[randomizer];

export async function GET() {
  try {
    let response;
    let provider;
    let linkProvider;

    switch (selected) {
      case "Waifu":
        provider = "Waifu.it";
        linkProvider = "https://waifu.it/";
        response = await axios.get(urlWaifu, {
          headers: {
            Authorization: process.env.WAIFU_IT_TOKEN,
          },
        });
        break;

      case "Zen":
        provider = "ZenQuotes";
        linkProvider = "https://zenquotes.io/";
        const resZ = await axios.get(urlZen);
        const zenQuotes: QuoteZen = resZ.data[0];
        const readyZenQuotes: QuoteTypes = {
          _id: 1,
          quote: zenQuotes.q,
          anime: "",
          author: zenQuotes.a,
        };
        response = { data: readyZenQuotes };
        break;

      case "Quotable":
        provider = "Quotable Quotes";
        linkProvider = "https://github.com/lukePeavey/quotable";
        const resQ = await axios.get(urlQuotable);
        const QuotableQuotes: Quotable = resQ.data[0];
        const readyQuotableQuotes: QuoteTypes = {
          _id: QuotableQuotes._id,
          quote: QuotableQuotes.content,
          anime: "",
          author: QuotableQuotes.author,
        };
        response = { data: readyQuotableQuotes };
        break;
    }

    return NextResponse.json(
      { data: response?.data, provider: provider, linkProvider: linkProvider },
      {
        status: 200,
        headers: {
          "Cache-Control":
            "no-store, no-cache, must-revalidate, proxy-revalidate",
          Pragma: "no-cache",
          Expires: "0",
          "Surrogate-Control": "no-store",
        },
      }
    );
  } catch (error: any) {
    return NextResponse.json(
      { error: "Ошибка при получении цитат", details: error.message || error },
      { status: 500 }
    );
  }
}

Затем я запрашиваю это так

 const fetchQuote = async () => {
    try {
      setIsLoading(true);
      const response = await fetch(`/api/quotes`, {
        cache: "no-store",
      });

      if (!response.ok) {
        throw new Error(`HTTP ошибка! статус: ${response.status}`);
      }

      const rawData = await response.json();
      const quotesData = rawData.data;
      setQuote(quotesData);
      setProvider(rawData.provider);
      setLinkProvider(rawData.linkProvider);
      setIsLoading(false);
    } catch (error) {
      setIsError(true);
      toast.error("Ошибка при получении мудрости. Пожалуйста, попробуйте снова.");
    }
  };

fetchQuote не получает больше одной цитаты. Приложение загружает её только один раз, когда fetchQuote вызывается снова, оно показывает те же данные, что и раньше.

Ожидается, что оно должно получать другие данные/цитаты.

На всякий случай я прикрепляю ссылку на репозиторий здесь
Репозиторий

Спасибо заранее

Ответ или решение

Проблема с получением новых цитат из API на Vercel

Здравствуйте!

Я рад помочь вам решить проблему, с которой вы столкнулись при развертывании вашего проекта на Vercel с использованием Next.js. Основная проблема, кажется, заключается в том, что ваше приложение не получает новые цитаты при повторном вызове API. Давайте разберёмся с вашей реализацией и возможными решениями.

1. Описание проблемы

Вы указали, что при вызове функции fetchQuote к API /api/quotes, приложение загружает данные только один раз, а при повторных вызовах возвращает те же данные. Это может означать, что API кеширует ответ или сам API-провайдер не предоставляет новые данные при каждом запросе.

2. Анализ кода

Ваш код для API выглядит корректно и стильно написан. Основные компоненты включают:

  • Вызов API через библиотеки Axios для получения случайных цитат.
  • Случайный выбор источника цитат (Waifu, Zen, Quotable).

Ваша функция GET возвращает данные с установленными заголовками управления кешированием:

"Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
Pragma: "no-cache",
Expires: "0",

Эти заголовки должны предотвращать кеширование. Если после повторного вызова всё равно возвращаются те же данные, то проблема может быть не в вашем коде, а в источнике цитат.

3. Возможные причины проблемы

  1. Кеширование на уровне API: Некоторые API могут кешировать ответы, если они предполагают, что данные не меняются часто. В этом случае, если вы делаете несколько запросов за короткий период времени, API может возвращать одно и то же значение.

  2. Ранее загруженные данные в браузере: Если браузер кеширует ответ от API, то даже с установленными заголовками, он может не выполнять новый запрос, а возвращать закешированные данные.

  3. Случайный выбор цитат: Поскольку выбор источника цитат случайный, он может вести себя так, что в некоторых случаях только один источник активно предоставляет данные.

4. Рекомендации по решению проблемы

Вот несколько рекомендаций для устранения вашей проблемы:

  1. Добавление параметров запроса: Вы можете добавить временную метку или случайный параметр к URL запроса в функции fetchQuote, чтобы принудить браузер и API выполнить новый запрос:

    const response = await fetch(`/api/quotes?timestamp=${new Date().getTime()}`, {
       cache: "no-store",
    });
  2. Проверка источников API: Убедитесь, что каждый из указанных вами API действительно возвращает уникальные данные при каждом запросе. Возможно, стоит протестировать каждый из них отдельно, чтобы увидеть, поведение каждого из них.

  3. Логирование запросов: Включите логирование в вашем API, чтобы видеть, сколько раз был вызван метод и возвращает ли он одни и те же данные.

  4. Ограничение кеширования на стороне клиента: Вы уже используете cache: "no-store" при запросе, что хорошо. Убедитесь, что это применяется во всех точках вашего приложения.

5. Заключение

Ваше приложение на Vercel с Next.js является отличным примером для работы с API, и я уверен, что предложенные изменения помогут вам решить проблему повторного получения данных. Не стесняйтесь экспериментировать с различными подходами к кешированию, чтобы определить, что именно вызывает ваше затруднение. Желаю удачи, и если у вас появится больше вопросов, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...