Removing from Cache

How to manually invalidate and remove items from the cache.

Overview

By default, JopiJS does not manage the cache lifecycle. Once a page is cached, it stays there indefinitely until:

  1. The server restarts (if using InMemoryCache).
  2. You manually remove it.
  3. If using memory cache: the garbage collector removes it to make space in case of low memory.

It is your responsibility to invalidate the cache when content changes (e.g., after editing a blog post or updating a product price).

You can remove items from the cache using JopiRequest (during a request) or directly via the Cache Engine (advanced usage).


1. Inside a Request object

When you are inside a route handler (API or Page logic), the JopiRequest object provides a helper method htmlCache_removeFromCache().

Method Signature

/**
 * Manually removes the cache entry for a specific URL or the current one.
 * @param url Optional URL to invalidate. Defaults to the current request URL.
 */
req.htmlCache_removeFromCache(url?: URL): Promise<void>

Example A: Removing the Current Route

If you are in a handler for a specific page and want to purge that exact page from the cache (e.g., after a POST request to it):

src/mod_blog/@routes/posts/[slug]/onPUT.ts
import { JopiRequest } from "jopijs";

export async function onPUT(req: JopiRequest) {
    // 1. Perform your data update
    await updatePost(req.req_body);

    // 2. Remove the current page from the cache
    await req.htmlCache_removeFromCache();

    // 3. Return success
    return req.res_returnResultMessage(true, "Post updated");
}

Example B: Removing a Different Route

Often, an action on one route (e.g., /admin/products/save) affects a different public page (e.g., /products/123). You can pass a URL object to target that specific page.

src/mod_admin/@routes/api/save-product/onPOST.ts
import { JopiRequest } from "jopijs";

export async function onPOST(req: JopiRequest) {
    const { productId, data } = await req.req_getBodyData();

    // 1. Update DB
    await db.products.update(productId, data);

    // 2. Construct the public URL of the product page
    //    Note: You must ensure the URL is absolute and matches exactly what is in the cache.
    const publicUrl = new URL(req.req_urlInfos.origin + "/products/" + productId);

    // 3. Remove it from cache
    await req.htmlCache_removeFromCache(publicUrl);

    return req.res_returnResultMessage(true);
}

Validation: When passing a custom URL object, ensure the protocol (http/https) and hostname match the cached entry exactly. JopiRequest helper helps with defaults, but being explicit is safer.


2. Using Cache Hooks

You can also control the cache behavior globally or per-route using Cache Hooks in your config.ts file. This allows you to programmatically invalidate or bypass the cache based on specific conditions (e.g., user roles, query parameters).

For a complete guide on available hooks, please refer to the Configuration page.

Example: Bypass Cache for Admins

You can check user roles in htmlCache_beforeCheckingCache and remove the page from cache (to force a fresh generation) or simply disable cache reading.

src/mod_main/@routes/config.ts
import { JopiRouteConfig } from "jopijs";

export default function(config: JopiRouteConfig) {
    config.onPage.htmlCache_beforeCheckingCache(async (req) => {
        // If user is admin, we remove the current page from cache
        // causing a fresh render (and cache update).
        if (req.role_userHasRole("admin")) {
            await req.htmlCache_removeFromCache();
        }
    });
}