Unable to cache JSON output from own API

I created a RESTful API for a database that is served on Cloudflare custom domain so I could cache queries, but I am unable to do so.

I am attempting to return cached JSON, but it continues to be dynamic. I also attempted to cache the output with a worker that uses fetch('https://myapi.com/cities', { cf: {cacheTtl: 30, cacheEverything: true} })

  case "/cities":
        try {
          const cities = await sql`SELECT * FROM cities`;
          return new Response(JSON.stringify(cities), {
            status: 200,
            headers: {
              "Content-Type": "application/json",
              "Cache-Control": "public, max-age=30",
              "CDN-Cache-Control": "max-age=30",
              "Cloudflare-CDN-Cache-Control": "max-age=30",
            },
          });
        } catch (error) {
          console.error(error);
          return new Response("Error fetching cities", { status: 500 });
        }

my response headers for https:://myapi.com/cities:

HTTP/2 200 
date: Sat, 13 Jan 2024 14:51:40 GMT
content-type: application/json
content-length: 397
cache-control: public, max-age=30
cdn-cache-control: max-age=30
cf-cache-status: DYNAMIC
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=4YFsUb4uDmBgpMQl2CEZYCf3raScLrcj%2BqEyBOuyjrgrYKrTrh7KeaWr3GKEc4tuNEOKlRQOJqFN2tjhkM198L9%2FQwzhEsyOQJfR701b4QBwUDNbysuEarGM%2B8Xq%2BIaxSTdWF6gjTrOJVr0kJqW1psEr"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 844e7567cefeceb9-SJC

When I try to cache APIs that are not served by Cloudflare and are also in JSON format with a worker using cf: {cacheTtl: 30, cacheEverything: true}, it works effortlessly. For example, the demo API https://httpbin.org/delay/0.3 is easily cachable inside a worker. While other APIs served by Cloudflare are unable to be cache the JSON output such as, https://uuid.rocks/.

Is the solution to not serve my RESTful API via Cloudflare? I was avoiding page/cache rules to get the benefits of tiered cache by utilizing fetch(), but I’m willing to do whatever is necessary.

Cloudflare does not cache JSON (or in your case, files without a file extension) by default. You can enable it by using a Cache Rule to set your API endpoint to “eligible for cache”.

If you refer to this warning, it does not relate to Cache Rules:

As I understand it, the cf parameter to the fetch call overrides the Cache Rule settings for this request, which only works if the target zone is in your own account (or not on CF at all).

I’ll be back in about an hour and can give this a try then.

Are the worker and the database actually in the same account?

1 Like

Thank you for the in-depth reply @Laudian.

I wasn’t aware tiered caching could work with page/cache rules. I couldn’t find this information in the Cloudflare documentation. Could you please clarify if page/cache rules indeed work with tiered caching?

Yes, everything is done in the same Cloudflare account. Both my database, hosted on a VPS and proxied through a custom domain on Cloudflare, and the worker are under the same Cloudflare account.

Cache Rules are the intended way to change cache behaviour. They definitely work with Tiered Caching.

1 Like