feat: cms cache
This commit is contained in:
@@ -2,10 +2,6 @@ import { NextResponse } from "next/server"
|
|||||||
|
|
||||||
import { bookingFlow } from "@/constants/routes/hotelReservation"
|
import { bookingFlow } from "@/constants/routes/hotelReservation"
|
||||||
|
|
||||||
import { resolve as resolveEntry } from "@/utils/entry"
|
|
||||||
import { findLang } from "@/utils/languages"
|
|
||||||
import { removeTrailingSlash } from "@/utils/url"
|
|
||||||
|
|
||||||
import { getDefaultRequestHeaders } from "./utils"
|
import { getDefaultRequestHeaders } from "./utils"
|
||||||
|
|
||||||
import type { NextMiddleware } from "next/server"
|
import type { NextMiddleware } from "next/server"
|
||||||
@@ -13,8 +9,6 @@ import type { NextMiddleware } from "next/server"
|
|||||||
import type { MiddlewareMatcher } from "@/types/middleware"
|
import type { MiddlewareMatcher } from "@/types/middleware"
|
||||||
|
|
||||||
export const middleware: NextMiddleware = async (request) => {
|
export const middleware: NextMiddleware = async (request) => {
|
||||||
const { nextUrl } = request
|
|
||||||
|
|
||||||
const headers = getDefaultRequestHeaders(request)
|
const headers = getDefaultRequestHeaders(request)
|
||||||
return NextResponse.next({
|
return NextResponse.next({
|
||||||
request: {
|
request: {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { resolve as resolveEntry } from "@/utils/entry"
|
|||||||
import { findLang } from "@/utils/languages"
|
import { findLang } from "@/utils/languages"
|
||||||
import { removeTrailingSlash } from "@/utils/url"
|
import { removeTrailingSlash } from "@/utils/url"
|
||||||
|
|
||||||
import { getDefaultRequestHeaders } from "./utils"
|
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
|
||||||
|
|
||||||
import type { NextMiddleware } from "next/server"
|
import type { NextMiddleware } from "next/server"
|
||||||
|
|
||||||
@@ -21,7 +21,10 @@ export const middleware: NextMiddleware = async (request) => {
|
|||||||
const pathNameWithoutLang = pathWithoutTrailingSlash.replace(`/${lang}`, "")
|
const pathNameWithoutLang = pathWithoutTrailingSlash.replace(`/${lang}`, "")
|
||||||
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
||||||
|
|
||||||
const { contentType, uid } = await resolveEntry(pathNameWithoutLang, lang)
|
const { contentType, uid } = await fetchAndCacheEntry(
|
||||||
|
pathNameWithoutLang,
|
||||||
|
lang
|
||||||
|
)
|
||||||
|
|
||||||
if (!contentType || !uid) {
|
if (!contentType || !uid) {
|
||||||
throw notFound(
|
throw notFound(
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ import {
|
|||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { internalServerError, notFound } from "@/server/errors/next"
|
import { internalServerError, notFound } from "@/server/errors/next"
|
||||||
|
|
||||||
import { resolve as resolveEntry } from "@/utils/entry"
|
|
||||||
import { findLang } from "@/utils/languages"
|
import { findLang } from "@/utils/languages"
|
||||||
|
|
||||||
import { getDefaultRequestHeaders } from "./utils"
|
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
|
||||||
|
|
||||||
import type { NextMiddleware } from "next/server"
|
import type { NextMiddleware } from "next/server"
|
||||||
|
|
||||||
@@ -40,8 +39,11 @@ export const middleware: NextMiddleware = async (request) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}`, "")
|
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}`, "")
|
||||||
const { uid, contentType } = await resolveEntry(pathNameWithoutLang, lang)
|
const { uid, contentType } = await fetchAndCacheEntry(
|
||||||
if (!uid) {
|
pathNameWithoutLang,
|
||||||
|
lang
|
||||||
|
)
|
||||||
|
if (!uid || !contentType) {
|
||||||
throw notFound(
|
throw notFound(
|
||||||
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
|
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
import { stringify } from "querystring"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
|
||||||
|
import { resolve as resolveEntry } from "@/utils/entry"
|
||||||
import { findLang } from "@/utils/languages"
|
import { findLang } from "@/utils/languages"
|
||||||
import { removeTrailingSlash } from "@/utils/url"
|
import { removeTrailingSlash } from "@/utils/url"
|
||||||
|
|
||||||
@@ -31,3 +35,43 @@ export function getDefaultRequestHeaders(request: NextRequest) {
|
|||||||
|
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContentStackResponse = {
|
||||||
|
contentType: string | null
|
||||||
|
uid: string | null
|
||||||
|
expiresAt: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const entryResponseCache: Map<string, ContentStackResponse> = new Map()
|
||||||
|
let size: number = 0
|
||||||
|
|
||||||
|
export const fetchAndCacheEntry = async (path: string, lang?: Lang) => {
|
||||||
|
const cacheKey = `${path + lang}`
|
||||||
|
const cachedResponse = entryResponseCache.get(cacheKey)
|
||||||
|
|
||||||
|
if (cachedResponse && cachedResponse.expiresAt > Date.now() / 1000) {
|
||||||
|
console.log("[CMS MIDDLEWARE]: CACHE HIT")
|
||||||
|
return cachedResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedResponse && cachedResponse.expiresAt < Date.now() / 1000) {
|
||||||
|
console.log("[CMS MIDDLEWARE]: CACHE STALE")
|
||||||
|
size -= JSON.stringify(cachedResponse).length
|
||||||
|
entryResponseCache.delete(cacheKey)
|
||||||
|
} else {
|
||||||
|
console.log("[CMS MIDDLEWARE]: CACHE MISS")
|
||||||
|
}
|
||||||
|
|
||||||
|
const { contentType, uid } = await resolveEntry(path, lang)
|
||||||
|
const expiresAt = Date.now() / 1000 + 3600
|
||||||
|
const entryCache = { contentType, uid, expiresAt }
|
||||||
|
size += JSON.stringify(entryCache).length
|
||||||
|
console.log("[CMS MIDDLEWARE] Adding to cache", entryCache)
|
||||||
|
console.log("[CMS MIDDLEWARE] Cache size (total)", size)
|
||||||
|
entryResponseCache.set(cacheKey, entryCache)
|
||||||
|
|
||||||
|
return {
|
||||||
|
contentType,
|
||||||
|
uid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { decryptData } from "@/utils/aes"
|
|||||||
import { resolve as resolveEntry } from "@/utils/entry"
|
import { resolve as resolveEntry } from "@/utils/entry"
|
||||||
import { findLang } from "@/utils/languages"
|
import { findLang } from "@/utils/languages"
|
||||||
|
|
||||||
import { getDefaultRequestHeaders } from "./utils"
|
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
|
||||||
|
|
||||||
import type { MiddlewareMatcher } from "@/types/middleware"
|
import type { MiddlewareMatcher } from "@/types/middleware"
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ export const middleware: NextMiddleware = async (request) => {
|
|||||||
|
|
||||||
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}/webview`, "")
|
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}/webview`, "")
|
||||||
|
|
||||||
const { uid } = await resolveEntry(pathNameWithoutLang, lang)
|
const { uid } = await fetchAndCacheEntry(pathNameWithoutLang, lang)
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
throw notFound(
|
throw notFound(
|
||||||
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
|
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
|
||||||
|
|||||||
Reference in New Issue
Block a user