DEV Community 👩‍💻👨‍💻

mixbo
mixbo

Posted on

My best practice use redis in javascript

Alt Text

node-redis support operation redis server in nodejs.
We use nuxt.js formwork in my team, when need cache data we create class to implement redis api like read, write, fetch methods let's show you code

// redis.js
const Redis = require('redis')
const { promisify } = require("util");
const DEFAULT_URL = 'redis://127.0.0.1:6379'
const PREFIX = '__prefix:'
const DEFAULT_EXPIRES = '7d'

export class Redis {
  constructor(url, options={} ) {
    this.url = url || DEFAULT_URL
    this.store = Redis.createClient({
      url: this.url,
      prefix: PREFIX,
    })
    this.client = {
      get: key => {
        const start = new Date()
        const getAsync = promisify(this.store.get).bind(this.store)
        return getAsync(key).finally(console.log({ action: 'READ', key, start }))
      },
      set: (key, val) => {
        const start = new Date()
        const setAsync = promisify(this.store.set).bind(this.store)
        return setAsync(key, val).finally(console.log({ action: 'WRITE', key, start }))
      },
      setex: (key, expires, val) => {
        const start = new Date()
        const setexAsync = promisify(this.store.setex).bind(this.store)
        return setexAsync(key, expires, val).finally(console.log({ action: 'WRITE', key, start, expires }))
      },
    }
  }

  disconnect(callback) {
    this.store.quit(callback)
  }

  async read(key) {
    const res = await this.client.get(key)
    if (!res) {
      return null
    }
    try {
      return JSON.parse(res)
    } catch (ex) {
      return null
    }
  }

  async write(key, value, expires) {
    if (!expires) {
      expires = DEFAULT_EXPIRES
    }
    await this.client.setex(key, expires, JSON.stringify(value))
  }

  async fetch(key, expires, callback) {
    let obj = await this.read(key)
    if (obj) {
      return obj
    }
    obj = await callback()
    await this.write(key, obj, expires)
    return obj
  }
}

Enter fullscreen mode Exit fullscreen mode

We can use redis cache more readable.

import Vue from 'vue'

const cache = ()=>{
  if(!Vue.$redis){
    Vue.$redis = new Redis(process.env.REDIS_URL, options)
  }
  return Vue.$redis
}

const list = cache().fetch('cache-key', async ()=>{
  const resp = await fetch('api/products')
  if(resp.err){
    return []
  }else{
    return resp.data
  }
})
Enter fullscreen mode Exit fullscreen mode

Call Vue.$redis fetch method first find if havs cache in redis with key cache-key.
If no cache found, fetch method just call callback fetch api/products then return the response and cache it.
If call fetch with cach-key again will return the data from redis.

Hope help you :)

Top comments (1)

Collapse
ziaadini profile image
yadollah ziaadini • Edited on

where do you call it? i'm trying to do this but getting error :
These dependencies were not found:

  • net in ./node_modules/redis/index.js
  • tls in ./node_modules/redis/index.js i am using nuxt i tried middleware when is calling server and nuxtServerInit but not working

🌚 Life is too short to browse without dark mode