-
-
Notifications
You must be signed in to change notification settings - Fork 764
Description
TLDR:
Even the docs say:
Because the cached data is serialized to JSON, it is important that the cached function does not return anything that cannot be serialized, such as Symbols, Maps, Sets…
I think there is room for improvement adding serialization/deseralization to cache functions
Environment
- Nitro version 2: latest (via Nuxt/NuxtHub v0.9.x)
- Deployment: Cloudflare Workers
Describe the bug
When using defineCachedEventHandler to cache a binary response (like MVT tiles returned as Buffer), Nitro serializes the Buffer to JSON format {"type":"Buffer","data":[...]} when storing in cache.
When the cached response is served, this JSON is returned instead of the raw binary data, breaking clients that expect binary content.
Reproduction
Minimal repro: https://github.com/onmax/nitro-binary-cache-repro (main branch = bug, fix/patch = pnpm patch fix using base64 encoding). the fix is not backwards compatible.
Expected behavior
Binary responses should be properly stored and retrieved from cache, maintaining their binary format.
Possible solutions
- Allow serialization/deseralization methods in
defineCachedFunctionanddefineCachedEventHandler - Detect Buffer/binary responses and store as base64, decode on cache hit
- Use a binary-safe serialization format for cache storage
Current workaround
Manually encode to base64 before caching and decode on retrieval:
export default defineCachedEventHandler(async (event) => {
const cached = await useStorage('cache').getItem(`tile:${key}`)
if (cached) {
return Buffer.from(cached as string, 'base64')
}
const mvt = await getTileMvt(...)
await useStorage('cache').setItem(`tile:${key}`, mvt.toString('base64'))
return mvt
}, { maxAge: 0 }) // Disable built-in caching, use manualDiscussion
I understand this is by design, but I think having a serialization/deseralization methods could benefit. What do maintainers think?
Feel free to close this issue if it was already discussed!