For a brief intro to setting up Redis with Clojure using Carmine, see my earlier post on setting up Redis with Clojure.
The most common killer use for Redis is as a key-value store. You simply get and set values in it like in a map. It’s very handy for site wide session storage with web apps, or even in more traditional applications.
Before getting into the first code sample, the naming convention for complex Redis key names is
1 |
global-name:more-specific:even-more-specific:my-key |
Breaking that down, use the key names in Redis similar to namespaces in and package names in other languages. Separate groups with colons ( : ). Individual names of groups and actual keys that are multiple words long, separate with dashes ( – ).
Here’s a very basic key-value set and get.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(ns redclojapp.core (:require [taoensso.carmine :as car :refer (wcar)]) ;; import the Carmine library (:gen-class)) ;;make sure your password is stored in a configuration file instead of in the connection string (defmacro wcar* [& body] `(car/wcar redis-connection ~@body)) (defn -main "Just a regular old main function" [& args] (wcar* (car/set "my-group:my-key" "mysecurejwt")) (println (wcar* (car/get "my-group:my-key")))) |
Running this function will result in mysecurejwt , Honestly, not that exciting, but often enough for many applications.
Now, let’s look at some of the additions to the simple mapping of keys and values that put Redis on the map. (Little coder joke there.)
First, you can set a timeout on a key-value pair in Redis. This makes the key “volatile”, and after the timeout, it just disappears.
A good use case for a volatile key is storing valid session token for users logged into your app. Often, when a user logs into a web app or other network based app, you want to assign a temporary token that goes away on its own after a certain amount of time (24 hours is common). Using the following code could accomplish that.
1 |
(wcar* (car/setex "my-group:my-key" (* 60 60 24) "mysecurejwt")) |
The trick here is to use the command, setex. setex takes a key, a second count, and a value as arguments. The above line sets the key my-group:my-key with value mysecurejwt to disappear in 24 hours.
If you want to test it in an app, you could use the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
(ns redclojapp.core (:require [taoensso.carmine :as car :refer (wcar)]) ;; import the Carmine library (:gen-class)) ;;make sure your password is stored in a configuration file instead of in the connection string (defmacro wcar* [& body] `(car/wcar redis-connection ~@body)) (defn -main "Just a regular old main function" [& args] (wcar* (car/setex "my-group:my-key" (* 1 6) "mysecurejwt")) (Thread/sleep 3000) (println (wcar* (car/get "my-group:my-key"))) (Thread/sleep 5000) (println (wcar* (car/get "my-group:my-key")))) |
Notice that the second time the value is accessed, it has expired because six seconds is up.
Sometimes, you want to invalidate a key. To remove a Redis key, use the del command.
1 |
(wcar* (car/del "my-group:my-key")) |
A common use case of del would be logging out and expiring the user’s token.
Here’s a larger example in context.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
(ns redclojapp.core (:require [taoensso.carmine :as car :refer (wcar)]) ;; import the Carmine library (:gen-class)) ;;make sure your password is stored in a configuration file instead of in the connection string (defmacro wcar* [& body] `(car/wcar redis-connection ~@body)) (defn -main "Just a regular old main function" [& args] (wcar* (car/setex "my-group:my-key" (* 1 6) "mysecurejwt")) (println (wcar* (car/get "my-group:my-key"))) (wcar* (car/del "my-group:my-key")) (println (wcar* (car/get "my-group:my-key")))) |
The docs for Carmine are a great place to start if you want to see other ways to use Clojure with Redis.
If you want to see a specific Clojure tutorial, please let me know on Twiter.