Trying to make a simple cache using a cloudflare worker with hono.

I was wondering if anyone could assist me with what I thought was going to be a simple usage of the cache api. My issue is that I cannot seem to get the cache to store the body properly... The cache key is getting stored and properly invalidated after 10 seconds but the body is always an empty object when the cache is matched.
app.get('/events', async (c) => {
try {
const cacheUrl = c.req.url
const cache = caches.default

// Check if our response is already in the cache
let response = await cache.match(cacheUrl)
console.log('body', JSON.stringify(response?.body))

if (!response) {
const { email } = c.req.query()
const config = getConfig(c.env)
const events = await findEvents(email, config)

response = new Response(JSON.stringify({ data: events }))
response.headers.append('Cache-Control', 's-maxage=10')

c.executionCtx.waitUntil(cache.put(cacheUrl, response.clone()))

return c.json({
data: events
})
} else {
console.log(`cache hit for ${cacheUrl}`)
}

return response
} catch (err: Error | any) {
return c.json(
{
error: {
message: err.message
}
},
500
)
}
})
app.get('/events', async (c) => {
try {
const cacheUrl = c.req.url
const cache = caches.default

// Check if our response is already in the cache
let response = await cache.match(cacheUrl)
console.log('body', JSON.stringify(response?.body))

if (!response) {
const { email } = c.req.query()
const config = getConfig(c.env)
const events = await findEvents(email, config)

response = new Response(JSON.stringify({ data: events }))
response.headers.append('Cache-Control', 's-maxage=10')

c.executionCtx.waitUntil(cache.put(cacheUrl, response.clone()))

return c.json({
data: events
})
} else {
console.log(`cache hit for ${cacheUrl}`)
}

return response
} catch (err: Error | any) {
return c.json(
{
error: {
message: err.message
}
},
500
)
}
})
The logs are showing up as this with an empty body when hitting the cache.
{
"outcome": "ok",
"scriptName": "some script name",
"exceptions": [],
"logs": [
{
"message": [
"body",
"{}"
],
"level": "log",
"timestamp": 1681117743889
},
{
"message": [
"cache hit for https://someurl/events?email=someemail@email.com"
],
"level": "log",
"timestamp": 1681117743889
}
],
"eventTimestamp": 1681117743883,
"event": {
"request": {
"url": "some url",
"method": "GET",
"headers": {
"content-type": "application/json"
}
},
"response": {
"status": 500
}
},
"id": 27
}
{
"outcome": "ok",
"scriptName": "some script name",
"exceptions": [],
"logs": [
{
"message": [
"body",
"{}"
],
"level": "log",
"timestamp": 1681117743889
},
{
"message": [
"cache hit for https://someurl/events?email=someemail@email.com"
],
"level": "log",
"timestamp": 1681117743889
}
],
"eventTimestamp": 1681117743883,
"event": {
"request": {
"url": "some url",
"method": "GET",
"headers": {
"content-type": "application/json"
}
},
"response": {
"status": 500
}
},
"id": 27
}
2 Replies
kian
kian14mo ago
console.log('body', JSON.stringify(response?.body)) will never show anything body is a ReadableStream and you can't serialise that If you want a text body, do await response.text() - or an object from JSON, await response.json()
bateswebtech
bateswebtech14mo ago
@kiannh Thank you. I got it working like this.
app.get('/events', async (c) => {
try {
const cacheUrl = c.req.url
const cache = caches.default

// Check if our response is already in the cache
let response = await cache.match(cacheUrl)

if (!response) {
const { email } = c.req.query()
const config = getConfig(c.env)
const events = await findEvents(email, config)

response = new Response(JSON.stringify({ data: events }))
response.headers.append('Cache-Control', 's-maxage=10')

c.executionCtx.waitUntil(cache.put(cacheUrl, response.clone()))

return c.json({
data: events
})
} else {
const { data } = (await response.json()) as EventResponse
return c.json({ data })
}
} catch (err: Error | any) {
return c.json(
{
error: {
message: err.message
}
},
500
)
}
})
app.get('/events', async (c) => {
try {
const cacheUrl = c.req.url
const cache = caches.default

// Check if our response is already in the cache
let response = await cache.match(cacheUrl)

if (!response) {
const { email } = c.req.query()
const config = getConfig(c.env)
const events = await findEvents(email, config)

response = new Response(JSON.stringify({ data: events }))
response.headers.append('Cache-Control', 's-maxage=10')

c.executionCtx.waitUntil(cache.put(cacheUrl, response.clone()))

return c.json({
data: events
})
} else {
const { data } = (await response.json()) as EventResponse
return c.json({ data })
}
} catch (err: Error | any) {
return c.json(
{
error: {
message: err.message
}
},
500
)
}
})
I wasn't able to directly return the response and I've also tried with response.clone(). Is there something I'm missing here?