عندما تحدث طلبات بحث متطابقة عدة مرات في نفس الشاشة.

يتم استخدام ذاكرة التخزين المؤقت للمتصفح مع createCsrCache من Core، ويتم إضافة callApiSsrCache من /next فقط عند الحاجة إلى ذاكرة التخزين المؤقت لبيانات خادم Next.js.


تعد ذاكرة التخزين المؤقت أيضًا جزءًا من commonService.

كود callApiClientCache/callApiServerCache في هذه الصفحة يشرح فقط جزء ذاكرة التخزين المؤقت من محول HTTP المشترك للمشروع. يمكن تكوين الخدمة المولدة لاستيراد هذه الوظيفة، لذا فإن رؤية الهيكل الكامل لـ rxjsHttpService.ts/commonService.ts أولاً يجعل موقع ودور كل غلاف أكثر وضوحًا.

ذاكرة التخزين المؤقت CSR (ذاكرة التخزين المؤقت للعميل)

createCsrCache<CacheName>()يوفر callApiCsrCache(callApiFn, serviceArgs, cacheOptions) وremoveCsrCache(cacheName).

ts
import {
  createCsrCache,
  type ServiceArguments,
} from "@byeolnaerim/typed-rx-http";
import type { paths as Paths } from "./@types/ApiTypes";

type CacheNames = "adminList" | "profile";

const csrCache = createCsrCache<CacheNames>();

export const callApiClientCache = <R>(
  args: ServiceArguments<Paths, any, any, R>,
  cache: {
    cacheName: CacheNames;
    cacheTime: number;
    cacheSize?: number;
  },
) => csrCache.callApiCsrCache(
  client.callApi,
  args as any,
  cache as any,
);

csrCache.removeCsrCache("adminList");
csrCache.removeCsrCache("any-prefix");

في بيئة الخادم، يتم استدعاء callApi الأصلي دون إنشاء خريطة ذاكرة التخزين المؤقت CSR. في المتصفح، يتم مشاركة نتائج Observable بنفس مفتاح الذاكرة المؤقتة باستخدام shareReplay.

محول Next.js: callApiSsrCache

مساعد SSR يستخدم next/cache (unstable_cache) في Next.js. إذا كان GET وcacheTime > 0، يتم استخدام force-cache + revalidate، بينما يتم تنفيذ الطلبات الأخرى باستخدام no-store.

  • يمكن حقن Cookie/Authorization لكل طلب باستخدام headersProvider.
  • إذا كان هناك onServer401 في 401، يتم تنفيذه.
ts
import type { paths as Paths } from "./@types/ApiTypes";
import { firstValueFrom } from "rxjs";
import {
  callApiSsrCache,
  redirectToUnauthorizedOnServer401,
} from "@byeolnaerim/typed-rx-http/next";

const apiUrl = process.env.NEXT_PUBLIC_API_URL!;

const headersProvider = async () => {
  const { cookies } = await import("next/headers");
  const cookieStore = await cookies();

  const cookieHeader = cookieStore
    .getAll()
    .map((c) => `${c.name}=${c.value}`)
    .join("; ");

  const accessToken = cookieStore.get("accessToken")?.value;

  return {
    ...(cookieHeader ? { Cookie: cookieHeader } : {}),
    ...(accessToken
      ? { Authorization: `Bearer ${accessToken}` }
      : {}),
  };
};

const obs$ = callApiSsrCache<Paths, { ok: true }, "adminList">({
  baseUrl: apiUrl,
  serviceArguments: { url: "/api/secure", method: "get" },
  cacheForService: { cacheName: "adminList", cacheTime: 10_000 },
  headersProvider,
  onServer401: redirectToUnauthorizedOnServer401,
});

const res = await firstValueFrom(obs$);

لا تخزن البيانات حسب المستخدم في الذاكرة المؤقتة.

عند تجميع المتصفح/الخادم في غلاف مشروع واحد.

يمكن أيضًا تجميع الخدمة العامة بحيث يتفرع المتصفح إلى createCsrCache، والخادم إلى callApiSsrCache. هذه هي نمط تكوين المشروع وليست هيكلًا أساسيًا لـ Core.

commonService.ts
ts
const csrCache = createCsrCache<"memberList" | "profile">();

export const callApiClientCache = (
  serviceArguments,
  cacheForService,
) => csrCache.callApiCsrCache(
  callApi,
  serviceArguments,
  cacheForService,
);

export const removeCsrCache = csrCache.removeCsrCache;
commonService.ts
ts
export const callApiServerCache = (serviceArguments, cacheForService) => {
  if (typeof window !== "undefined") {
    return callApiClientCache(serviceArguments, cacheForService);
  }

  return from(
    import("@byeolnaerim/typed-rx-http/next"),
  ).pipe(
    mergeMap(({ callApiSsrCache }) =>
      callApiSsrCache({
        baseUrl: process.env.NEXT_PUBLIC_API_URL || "",
        serviceArguments,
        cacheForService,
        headersProvider,
      }),
    ),
  );
};

عند استخدام غلاف ذاكرة التخزين المؤقت في الخدمة المولدة تلقائيًا، يجب ربط هذا الغلاف فقط بنقاط النهاية التي تحتاج إلى وظيفة ذاكرة التخزين المؤقت، بينما يتم استخدام callApi العادي لبقية الطلبات.

© 2026 بيولناريم. جميع الحقوق محفوظة.مقدمةسياسة معالجة المعلومات الشخصية