Joao Bairrada
Joao Bairrada

Reputation: 93

NUXT caching API requests

I'm developing a project using Nuxt and I need to update the data 15 in 15 seconds, the API is a third party API and has a 100 API calls limit per day. I need to be able to make only one API call every 15 seconds without counting the number of users online, so if I have 10k online users it makes only 1 request.

What I've tried so far.

On my store I have this:

async getData({ commit }) {
 await this.$axios
  .get('/api/breeds/image/random', {
  
  })
  .then(function (response) {
    commit('SET_DATA', response.data)
  })
},

I created a middleware, and I'm making a call on server side so on Network tab on dev tools don't appear any request call, but unfortunately every time I refresh the page It stills counting as one request, I need some sort of cache.

export default async function ({ store, from }) {
  let isInitialPageLoad = !from

  if (isInitialPageLoad) {
    await store.dispatch('getData')
  }
}

and lastly I enabled the proxy on axios on nuxt.config.js

Any idea how to cache and update without making requests based on online users and without refreshing the page?

Upvotes: 1

Views: 16637

Answers (4)

Leonardo Rick
Leonardo Rick

Reputation: 788

Nuxt 3.8 now supports cache out of the box!

Check: https://github.com/nuxt/nuxt/issues/15445 And: https://www.youtube.com/watch?v=aQPR0xn-MMk

Upvotes: 0

Ario
Ario

Reputation: 659

I had a similar issue and Redis is coming to help.

I would recommend to handle these kind of API calls in server side and inside your frontend just call your local API to feeding users. here is a solution for your problem with async-redis.

// IMPORT
const asyncRedis = require('async-redis')

// INIT CLIENT
const redis_client = asyncRedis.createClient()
redis_client.on('error', (err) => {
  console.log('Error ' + err)
})

// API 
const GET_RANDOM_IMG_CACHE_TIME = 15
app.post('/get_random_image', async (req, res) => {
  const key = 'RANDOM_IMG' 
  let random_image_data = ''
  const value = await redis_client.get(key)
  if (value !== null) {
    // console.log(key, '   :found in cache');
    random_image_data = JSON.parse(value) 
  } else {
    const get_random_image_responce = await this.$axios.get('/api/breeds/image/random', {})
    random_image_data = get_random_image_responce.data
    await redis_client.setex(key, GET_RANDOM_IMG_CACHE_TIME , JSON.stringify(random_image_data))
  }
  res.status(200).send(random_image_data)
})

Upvotes: 0

Cosimo Chellini
Cosimo Chellini

Reputation: 1730

I strongly recommend that you use the service workers https://web.dev/service-worker-caching-and-http-caching/ (native browser functions) to handle this kind of caching.

With service workers, especially with a library called workbox, you have the ability to save any calls made by the client, and manage any type of call differently (some examples https://developers.google.com/web/tools/workbox/modules/workbox-strategies)

To use it on nuxt you must have the pwa module (section for workbox https://pwa.nuxtjs.org/workbox/)

Upvotes: 3

zia
zia

Reputation: 278

ok you need to cache your api request on the server just install and use this package nuxt-perfect-cache

npm i nuxt-perfect-cache

// nuxt.config.js

modules: [
    [
        'nuxt-perfect-cache',
        {
          disable: false,
          appendHost: true,
          ignoreConnectionErrors:false, //it's better to be true in production
          prefix: 'r-',
          url: 'redis://127.0.0.1:6379',
          getCacheData(route, context) {                    
              return false//this is for page cache you don't need it                  
          }
        }
      ]
]

this module will enject cool method cacheFetch

so for cache api request

asyncData(ctx) {
    return ctx.$cacheFetch({ key: 'myApiKey', expire: 60 * 2 }, () => {
      console.log('my callback called*******')
      return ctx.$axios.$get('https://jsonplaceholder.typicode.com/todos/1')
    })
  }

don't forget to install redis in your machine

Upvotes: 1

Related Questions