Кэширование ответов API на стороне сервера по маршрутам в NextJSJavascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Кэширование ответов API на стороне сервера по маршрутам в NextJS

Сообщение Anonymous »

Я пытаюсь кэшировать данные между маршрутами. Я попробовал несколько вариантов, но не могу понять, как это сделать. Кажется, такая простая и очевидная задача. Мой вариант использования — это раздел «Профиль» на веб-сайте, который позволяет обновлять данные через форму (на стороне клиента). На маршрутах [lang]/foo/bar имеется множество страниц. В настоящее время я вызываю свой API при каждом изменении маршрута.
Я начинаю с этого файла, он вызывается с множества страниц и серверных компонентов:

Код: Выделить всё

"use server"

export const getData = async () => {
const data = await fetch("http://foo/getProfileData", {
next:{ revalidate: 60 }
});

return data.json()
}
Но это не устраняет дублирование вызовов, и я вижу много запросов к моему API.
Поэтому я пробую оболочку кэша React:

Код: Выделить всё

"use server"
import { cache } from "react";

export const getData = cache(async () => {
const data = await fetch("http://foo/getProfileData", {
next:{ revalidate: 60 }
});

return data.json()
})
Некоторый прогресс, я уменьшил количество запросов для каждого маршрута, но при переключении маршрутов снова вызывается Foo API.
Поэтому я пытаюсь будьте немного умнее и воспользуйтесь преимуществами кэширования модулей Node:

Код: Выделить всё

import "server-only";

export class ServerCache {
private data: null | T = null;
private expirationMs: number;
private timestamp: null | number = null;

constructor(expirationMs: number) {
this.expirationMs = expirationMs;
}

get(): null | T {
const shouldRevalidate =
!this.data || this.getElapsedMs() > this.expirationMs;

if (shouldRevalidate) {
return null;
}
return this.data;
}

getElapsedMs() {
return this.timestamp ? Date.now() - this.timestamp : Infinity;
}

getRemainingSeconds() {
return (this.expirationMs - this.getElapsedMs()) / 1000;
}

invalidate() {
this.data = null;
this.timestamp = null;
}

set(data: T) {
this.data = data;
this.timestamp = Date.now();
}
}
и

Код: Выделить всё

"use server"

const cache = new ServerCache(60*1000)

export const getData = async () => {

if (cache.get()) return data;

const data = await fetch("http://foo/getProfileData", {
next:{ revalidate: 60 }
});

const updatedData = await data.json();

cache.set(updatedData)

return updatedData
}

export const revalidate = () => cache.invalidate()
Это снова работает, но теперь я не могу аннулировать кеш вручную, потому что каждый раз, когда этот файл импортируется, он создает новый экземпляр, поэтому вы никогда не сможете очистить «правильный» кеш.Поэтому я попытался воспользоваться глобальным состоянием:

Код: Выделить всё

declare global {
// eslint-disable-next-line no-var
var meCache: ServerCache | undefined;
}

if (!global.meCache) {
console.log("Initializing globalCache module");
global.meCache = new ServerCache(GET.me.revalidate * 1000);
}

export const me = global.meCache;

и импортирую это в свой файл getData, но происходит то же самое: я просматриваю журнал несколько раз и поэтому не могу вручную очистить кеш.
Это Кажется, это обычный вариант использования отношений между сервером и клиентом, но я не могу понять, как создать кеш между маршрутами, который я могу очистить при необходимости.

Подробнее здесь: https://stackoverflow.com/questions/793 ... -in-nextjs
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Javascript»