简体   繁体   中英

Caching api calls in clojure

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM