I want to implement caching of api in clojure, In my application I have api's which are called for some of the functionalities. I want to reduce that api calls. I want to use clojure.core.cache.wrapped
which is implemented upon clojure.core.cache
. I want to cache my api call response base on the url.
The url is GET and has query inside the url that differentiates the response
for eg
http://localhost:3000/:clientid/get_data
Sample code
(:require [clojure-mauth-client.request :refer [get!]]
[clojure.core.cache.wrapped :as cw])
(def my-cache (cw/ttl-cache-factory {} :ttl 60000))
(defn get-data-caller [cid]
(cw/lookup-or-miss my-cache cid get-data))
(defn get-data [cid]
(let [req-url (str "/api/get-data?id=" cid)
response (retry-request (sign-credentials #(get! base-url req-url)) 3)]
(println response))))
I want to implement in a way that it caches depending on the cid
.
In above code 3 is max-retries
With current implementation I am getting below error.
In my current code it is calling the api again and again
I got the solution, The main mistake I made here is that I implemented this in
get-data-caller
lookup-or-miss
actually accepts 3 params
lookup-or-miss [cache key fn]
Here
1. cache is the one that we create.
2. key that we want to use as 'key' in our caching
3. The third has to be the function, that takes 'key' as an arg and gets data for us.
So lookup-or-miss will first check if the we have cached data for the 'key' passed, if not then, that will be passed as an arg to the third arg (i.e the fn) and get the fresh data.
If the cache data is not present for the key, then the fn in the third arg will be called with key as arg to get the data.
With above understanding I did rewrite my code as below
(:require [clojure-mauth-client.request :refer [get!]]
[clojure.core.cache.wrapped :as cw])
(def my-cache (cw/ttl-cache-factory {} :ttl 60000))
(defn http
[url]
(retry-request (sign-credentials #(get! url)) 3))
(defn get-data-caller [cid]
(get-data cid))
(defn get-data [cid]
(let [req-url (str "/api/get-data?id=" cid)
response (cw/lookup-or-miss my-cache req-url http-request)]
(println response))))
So here lookup-or-miss will search req-url
key in my-cache
, if present it will directly return the value stored, if not then it will call http-request
with req-url
as an arg
So lookup-or-miss will be executed something like this;
pseudo code for understanding
(if (contains? my-cache req-url)
(:req-url my-cache)
(http-request req-url))