Skip to content

Instantly share code, notes, and snippets.

@mallendeo
Last active February 1, 2021 23:29
Show Gist options
  • Save mallendeo/24fafd68bd49e7fad59364e1ca95d1c1 to your computer and use it in GitHub Desktop.
Save mallendeo/24fafd68bd49e7fad59364e1ca95d1c1 to your computer and use it in GitHub Desktop.
Custom ioredis based redis client
import Redis, { RedisOptions } from 'ioredis'
import ms from 'ms'
import config from '../config'
import { logger } from './logger' // winston, pino, ...
export const toSeconds = (time: string | number): number =>
typeof time === 'number' ? time : ms(time) / 1000
export interface CustomRedis extends Redis.Redis {
getJson?(key: string): Promise<unknown>
setJson?(key: string, val: unknown): Promise<unknown>
hgetJson?(key: string, field: string): Promise<unknown>
hsetJson?(key: string, field: string, val: unknown): Promise<unknown>
setKeyExp?(
key: string,
timeStr: string | number,
isHash: boolean,
expThreshold?: string | number,
): Promise<unknown>
}
const tryParse = (str: string) => {
if (!str) return str
try {
return JSON.parse(str)
} catch (err) {
return str
}
}
export const createClient = (opts: RedisOptions = {}): CustomRedis => {
const { prefix } = config.redis
const keyPrefix = prefix ? `${prefix}:${opts.keyPrefix ? `${opts.keyPrefix}:` : ''}` : undefined
const client: CustomRedis = new Redis({
host: config.redis.host,
password: config.redis.password,
db: config.redis.defaultDb,
...opts,
keyPrefix,
})
client.setJson = async (key, val) => client.set(key, JSON.stringify(val))
client.getJson = async (key) => tryParse(await client.get(key))
client.hsetJson = async (key, field, val) => client.hset(key, field, JSON.stringify(val))
client.hgetJson = async (key, field) => tryParse(await client.hget(key, field))
/**
* Set expiration in seconds for a given redis key
*
* @param key
* @param timeStr any `ms` lib compatible string, any integer will be in seconds
*
* @example
* redis.setKeyExp('cache', '1 day', true)
*/
client.setKeyExp = async (key, timeStr) => {
const exists = await client.exists(key)
if (!exists) throw Error(`key "${key}" does not exist`)
return client.expire(key, toSeconds(timeStr))
}
client.on('error', logger.error)
return client
}
export const defaultClient = createClient({ lazyConnect: true })
export default createClient
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment