2024-12-11

Cache cURL locally with Redis and Node.js

just wanted to use redis locally and came up with this simple idea

assumes node.js and redis are installed on your macos

code

 mkdir curl-with-redis-cache
 cd curl-with-redis-cache
 npm init -y
 npm i node-fetch redis
 touch index.js
// package.json
{
  ...
  "type": "module",
  ...
}
// index.js
import { createClient } from "redis"
import fetch from "node-fetch"
import { argv } from "process"
 
const CACHE_TIME = 60 * 60 * 1
const redisUrl = "redis://127.0.0.1:6379"
const client = createClient({ url: redisUrl })
client.on("error", (error) => console.log("redis client error: ", error))
 
await client.connect()
 
const args = argv.slice(2)
const url = args[0]
 
if (!url) {
  console.log("usage: curl0 <url>")
  process.exit(1)
}
 
function isValidUrl(url) {
  try {
    new URL(url)
    return true
  } catch (error) {
    return false
  }
}
 
async function fetchWithRedisCache(url) {
  if (!isValidUrl(url)) {
    console.log("error: invalid url")
    process.exit(1)
  }
 
  try {
    const cachedData = await client.get(url)
    if (cachedData) {
      console.log(cachedData)
      return
    }
    const response = await fetch(url)
    if (!response.ok) {
      console.log("error: http status not ok")
      process.exit(1)
    }
 
    const data = await response.text()
    client.set(url.trim(), data, {
      EX: CACHE_TIME,
    })
    console.log(data)
  } catch (error) {
    console.log("error fetching the url: ", error.message)
    process.exit(1)
  }
}
 
async function main() {
  try {
    await fetchWithRedisCache(url)
  } finally {
    await client.quit()
  }
}
 
await main()

usage

 node index.js https://jsonplaceholder.typicode.com/posts/1

alias

# ~/.zshrc
# curl0: run curl with local redis cache
alias curl0="node /Users/.../curl-with-redis-cache/index.js"
 chmod +x index.js
# use alias
 curl0 https://jsonplaceholder.typicode.com/posts/1

some redis commands

 redis-cli ping
PONG
 
 redis-cli
127.0.0.1:6379> dbsize
(integer) 2
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
127.0.0.1:6379> get key1
...
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> exit

note

using a local redis cache doesn't necessarily make it run faster than just using curl