Beast80K
Beast80K

Reputation: 1387

NextJS 14 returns old cached data despite external API returns error response after revalidation period?

Description :

  1. I have a API route handler ping, which gets data from external API. This external API is an mock API(made using Mockoon Tool) which returns random statuses like 200, 404, 429, 503 after it gets HIT.
  2. I have applied next: { revalidate: 10 } & export const dynamic = 'force-dynamic' in my API route handler, & also added console.logs to see response statuses.
  3. When I HIT this API route handler http://localhost:3000/api/ping from ThunderClient it returns data from cache. Even if external API sends error statuses (visible in Mockoon Tool logs).
  4. It never caches error statuses (404, 429, 503) but after getting a 200 status response, it just ignores every error response given by external API.
  5. If I remove next: { revalidate: 10 } it works but, HITs external API everytime for each request which is basically not what I want.

NextJS Version : "14.1.4"

Current Behavior :

API route handler returns old cached data (which has status 200) even if external API gives error status(404, 429, 503).

Expected Behavior :

I want this API route handler to return cached data(whatever it is error or data) if revalidation time is remaining, else fetch fresh data & return it as it is (whatever it is error or data).

enter image description here

API Route Handler Code :

export const dynamic = 'force-dynamic'
import { NextResponse } from 'next/server'

export async function GET() {
    try {

        console.log("PING : ", new Date().toLocaleTimeString())

        let res = await fetch(`http://localhost:4000/ping`,
            {
                method: "GET",
                next: { revalidate: 10 }
            })

        let data = await res.json()
        console.log("DATA : ", data);

        if (!res.ok) {
            console.log("Not OK", res.status);
            return NextResponse.json({ error: data.error }, {
                status: res.status,
                statusText: res.statusText
            })
        }
        else {
            console.log("OK", res.status);
            return NextResponse.json({ ...data }, {
                status: res.status,
                statusText: res.statusText,
            })
        }
    }
    catch (e) {
        console.log("Error");
        return NextResponse.json({ error: e.toString() }, {
            status: 500,
            statusText: "Internal Server Error"
        })
    }
}

So where should I update code, what should I do to by which I can cache external API responses as it is ?

Helpful Links :

Upvotes: 0

Views: 400

Answers (1)

Beast80K
Beast80K

Reputation: 1387

Sadly, i didn't found any solution to this behavior.

I then implemented a seperate NodeJS + ExpressJS, server with extra features like Caching, Rate Limiting, CORS etc now this server caches whatever response I want, & it also helped in security aspects & give me more options.

Other Problems I faced :

  • Using Fetch API was hectic because it considers some error responses as success, despite status code received & I have to check response.ok is true or not.
  • Its hectic to convert data to JSON, as I have many API route handlers.

Upvotes: 0

Related Questions