I’m having trouble with my Remix app making way too many API calls to an external service. I set up a loader function in my main route that calls a restaurant review API, but something weird is happening in production.
I thought I was being smart by caching the API response in a session cookie that expires after 1 hour. The idea was simple - if the data exists in the session, use that instead of making another API call. This seemed to work fine during development.
But when I deployed to production, my API usage went crazy. I’m seeing over 300 API calls per day, even on days when my analytics show zero visitors. That makes no sense to me.
Here’s the basic structure of my loader:
export async function loader({ request }: LoaderFunctionArgs) {
const userSession = await getUserSession(request.headers.get('Cookie'));
let restaurantData = null;
let consent = null;
let notification = null;
let errorMsg = null;
if(userSession.has("consent")){
consent = userSession.get("consent");
}
if(userSession.has("restaurant")){
restaurantData = JSON.parse(userSession.get("restaurant") as string);
} else {
const requestOptions = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${process.env.RESTAURANT_API_KEY}`,
'Content-Type': 'application/json'
}
};
const response = await fetch('https://api.restaurant-reviews.com/v2/locations/123', requestOptions);
restaurantData = await response.json();
userSession.set("restaurant", JSON.stringify(restaurantData));
}
if (userSession.has("notification")) {
notification = userSession.get("notification");
}
if (userSession.has("errorMsg")) {
errorMsg = userSession.get("errorMsg");
}
return json({ notification, errorMsg, restaurantData, consent }, {
headers: {
'Set-Cookie': await saveSession(userSession),
},
});
}
My session setup looks like this:
import { createCookieSessionStorage } from "@remix-run/node";
const { getUserSession, saveSession, clearSession } =
createCookieSessionStorage({
cookie: {
name: "__app_session",
httpOnly: true,
maxAge: 3600, // 1 hour
path: "/",
sameSite: "lax",
secrets: ["my-secret-key"],
secure: true,
},
});
export { getUserSession, saveSession, clearSession };
Has anyone experienced this before? I had to remove the API calls completely because I can’t figure out what’s causing this behavior. It makes me worried about using Remix in production if I can’t control when loaders execute.