Last active
February 1, 2021 23:29
-
-
Save mallendeo/24fafd68bd49e7fad59364e1ca95d1c1 to your computer and use it in GitHub Desktop.
Custom ioredis based redis client
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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