New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Caching of external api calls from within SvelteKit #3642
Comments
I know that other SSG projects have this and it's wonderful, the one I'm specifically speaking of is 11ty / eleventy - Quick Tip #009—Cache Data Requests |
You have a variety of options, depending on exactly what behaviour you want. You can return a cache-control header from your endpoint... export async function get() {
const res = await fetch(`https://dev.to/api/articles?username=dreitzner`);
return {
headers: {
'cache-control': 'public, max-age=3600'
},
body: {
articles: await res.json()
}
}
} ...or, if you wanted to respect the original cache headers (probably not, since it looks like the dev.to API uses export function get() {
return fetch(`https://dev.to/api/articles?username=dreitzner`);
} ...or, since the API doesn't need a private key, you could fetch the data in <script context="module">
export async function load({ fetch }) {
const res = await fetch(`https://dev.to/api/articles?username=dreitzner`);
return {
maxage: 3600,
props: {
articles: await res.json()
}
};
}
</script> Personally I'd probably opt for the first one, since it means you have the opportunity to slim down the response to just the bits you need. Though I'd typically pick a much lower maxage (a few minutes at most, rather than an hour), so that you can handle getting slashdotted (oops, might have just aged myself) while avoiding stale content. |
@Rich-Harris thank you for your detailed answer.
The approach I would like to see, would be on the platform side with a standard interface/approach inside sveltkit that will be transformed by the adapter. If I'm not mistaken cloudflare approuches this by adding a parameter (cf) to their fetch options: const devTo = await fetch(
'https://dev.to/api/articles?username=dreitzner',
{
headers: {
'api-key': `${import.meta.env.VITE_DEVTO_API_KEY}`,
},
mode: 'cors', // no-cors, *cors, same-origin
credentials: 'same-origin', // include, *same-origin, omit
cf: {
// Always cache this fetch regardless of content type
// for a max of 60 seconds before revalidating the resource
cacheTtl: 60,
cacheEverything: true,
},
}
) This should be cached inside the worker context and the api should not be called until the cache is invalid. Another good example usecase (from my daily business) would be product data, that updates only once a day. I hope I articulated what I would like to achieve well enough :) Thanks again |
We had a similar requirement where we call data from our API that doesn't change much and didn't want to load the data from the API each time, we ended up using the https://github.com/jaredwray/keyv library within our endpoint with something like this:
|
I have a similar issue where I want the server to cache the response, but my server is, well, serverless. So can't use something like I like the idea of something writing out a static file and then all client-side pages access this file, and periodically this file gets rebuilt as data changes/goes stale. Not sure how to do that, and it's probably out of scope for Sveltekit to handle I guess |
I just learned about the "Incremental Static Regeneration" ergonomics in Next.js and they truly are on the next level. |
It depends.
Yes, we definitely want to adopt ISR (particularly on-demand ISR, where revalidation is triggered by a webhook notifying of a change, rather than requests). It's something we hope to implement after 1.0: #661 |
Going to close this as I don't think there's much we can or should do, short of #661, beyond the existing ability to set |
I'm dynamically generating images as well as json data and I've tried setting Here's an example image resource served on a custom domain with the I would expect to see a https://developers.cloudflare.com/cache You'll notice that https://smol.xyz/favicon.png does behave this way as it's served as a static uploaded image. So why does that work while the dynamic images don't? |
Answering my own question: You have to implement the CF Worker https://developers.cloudflare.com/workers/runtime-apis/cache/ API per route and then ensure you pass the headers from any retrieved cache response (the piece I was missing) which includes the Would be nice (and maybe possible I just don't know where) to intercept all incoming Worker requests to inspect it for a cache key. I tried the hooks |
For anyone curious stumbling upon this in the future. First "Hi!" 👋
Then use it something to the tune of
|
I have added this cache-control header to my page's index.ts endpoint, but I can't see that it is having any effect. My site is hosted on Vercel and the response headers say: cache-control: public, max-age=0, must-revalidate If I go to /page/__data.json it returns the correct "public, max-age=3600" cache headers. But visiting /page/ directly does not seem to trigger the cache. Visiting the __data.json returns a response within 50ms so the cache is working for the actual endpoint. But visiting the page itself is several hundred ms, which is consisent with a completely uncached page. Is there some other recommended way to cache pages/routes that are rendered with data from endpoints with the same name? As in: /page/index.ts -- fetches data and returns it as props |
For those that stumble upon this issue. I was doing Cheers! |
@multiplehats bro anyone that says they haven't been there is straight lying through their teeth...my fav is when it's something you've done before, wanna beat myself senseless with a frozen tuna lol. |
@multiplehats @blujedis Aren't HTTP Headers case-insensitive, what's the difference? |
Thought so too. But that happened to solve it for me at the time. This is a long time ago though. |
Describe the problem
The following situation:
On my new personal website, I wanted to call the dev.to api to show the links in the blog section.
I made it work by adding an json endpoint and including it in the SSR.
The problem I see is that with every request to
/blog
the dev.to api will be called again (with a lot of traffic the might block me).So if I could cache the response for about 1 hour, I could drastically reduce the api calls even when a lot of traffic hits.
As far as I understand it cloudflare has some functionallity like that.
Cloudflare docs
Vercel docs
Describe the proposed solution
I would be nice to have something similar to cloudflare, where we use cache controll on the request/response.
Alternatives considered
No response
Importance
nice to have
Additional Information
No response
The text was updated successfully, but these errors were encountered: