BREAKING for the very small minority of folks that use `nippy/stress-data`. Changes: 1. Make `nippy/stress-data` a function It's unnecessarily wasteful to generate and store all this data when it's not being used in the common case. 2. Make data deterministic The stress data will now generally be stable by default between different versions of Nippy, etc. This will help support an upcoming test for stable serialized output.
142 lines
No EOL
5.1 KiB
Markdown
142 lines
No EOL
5.1 KiB
Markdown
# Setup
|
|
|
|
Add the [relevant dependency](../#latest-releases) to your project:
|
|
|
|
```clojure
|
|
Leiningen: [com.taoensso/nippy "x-y-z"] ; or
|
|
deps.edn: com.taoensso/nippy {:mvn/version "x-y-z"}
|
|
```
|
|
|
|
And setup your namespace imports:
|
|
|
|
```clojure
|
|
(ns my-app (:require [taoensso.nippy :as nippy]))
|
|
```
|
|
|
|
# De/serializing
|
|
|
|
As an example of what it can do, let's take a look at Nippy's own reference [stress data](https://taoensso.github.io/nippy/taoensso.nippy.html#var-stress-data):
|
|
|
|
```clojure
|
|
{:nil nil
|
|
:true true
|
|
:false false
|
|
:false-boxed (Boolean. false)
|
|
|
|
:char \ಬ
|
|
:str-short "ಬಾ ಇಲ್ಲಿ ಸಂಭವಿಸ"
|
|
:str-long (reduce str (range 1024))
|
|
:kw :keyword
|
|
:kw-ns ::keyword
|
|
:sym 'foo
|
|
:sym-ns 'foo/bar
|
|
:kw-long (keyword (reduce str "_" (range 128)) (reduce str "_" (range 128)))
|
|
:sym-long (symbol (reduce str "_" (range 128)) (reduce str "_" (range 128)))
|
|
|
|
:byte (byte 16)
|
|
:short (short 42)
|
|
:integer (int 3)
|
|
:long (long 3)
|
|
:float (float 3.1415926535897932384626433832795)
|
|
:double (double 3.1415926535897932384626433832795)
|
|
:bigdec (bigdec 3.1415926535897932384626433832795)
|
|
:bigint (bigint 31415926535897932384626433832795)
|
|
:ratio 22/7
|
|
|
|
:list (list 1 2 3 4 5 (list 6 7 8 (list 9 10 (list) ())))
|
|
:vector [1 2 3 4 5 [6 7 8 [9 10 [[]]]]]
|
|
:subvec (subvec [1 2 3 4 5 6 7 8] 2 8)
|
|
:map {:a 1 :b 2 :c 3 :d {:e 4 :f {:g 5 :h 6 :i 7 :j {{} {}}}}}
|
|
:map-entry (clojure.lang.MapEntry/create "key" "val")
|
|
:set #{1 2 3 4 5 #{6 7 8 #{9 10 #{#{}}}}}
|
|
:meta (with-meta {:a :A} {:metakey :metaval})
|
|
:nested [#{{1 [:a :b] 2 [:c :d] 3 [:e :f]} [#{{[] ()}}] #{:a :b}}
|
|
#{{1 [:a :b] 2 [:c :d] 3 [:e :f]} [#{{[] ()}}] #{:a :b}}
|
|
[1 [1 2 [1 2 3 [1 2 3 4 [1 2 3 4 5 "ಬಾ ಇಲ್ಲಿ ಸಂಭವಿಸ"] {} #{} [] ()]]]]]
|
|
|
|
:regex #"^(https?:)?//(www\?|\?)?"
|
|
:sorted-set (sorted-set 1 2 3 4 5)
|
|
:sorted-map (sorted-map :b 2 :a 1 :d 4 :c 3)
|
|
:lazy-seq-empty (map identity ())
|
|
:lazy-seq (repeatedly 64 #(do nil))
|
|
:queue-empty (into clojure.lang.PersistentQueue/EMPTY [:a :b :c :d :e :f :g])
|
|
:queue clojure.lang.PersistentQueue/EMPTY
|
|
|
|
:uuid (java.util.UUID. 7232453380187312026 -7067939076204274491)
|
|
:uri (java.net.URI. "https://clojure.org")
|
|
:defrecord (nippy/StressRecord. "data")
|
|
:deftype (nippy/StressType. "data")
|
|
:bytes (byte-array [(byte 1) (byte 2) (byte 3)])
|
|
:objects (object-array [1 "two" {:data "data"}])
|
|
|
|
:util-date (java.util.Date. 1577884455500)
|
|
:sql-date (java.sql.Date. 1577884455500)
|
|
:instant (java.time.Instant/parse "2020-01-01T13:14:15.50Z")
|
|
:duration (java.time.Duration/ofSeconds 100 100)
|
|
:period (java.time.Period/of 1 1 1)
|
|
|
|
:throwable (Throwable. "Msg")
|
|
:exception (Exception. "Msg")
|
|
:ex-info (ex-info "Msg" {:data "data"})
|
|
|
|
:many-longs (vec (repeatedly 512 #(rand-nth (range 10))))
|
|
:many-doubles (vec (repeatedly 512 #(double (rand-nth (range 10)))))
|
|
:many-strings (vec (repeatedly 512 #(rand-nth ["foo" "bar" "baz" "qux"])))
|
|
:many-keywords (vec (repeatedly 512
|
|
#(keyword
|
|
(rand-nth ["foo" "bar" "baz" "qux" nil])
|
|
(rand-nth ["foo" "bar" "baz" "qux" ]))))}
|
|
```
|
|
|
|
Serialize it:
|
|
|
|
```clojure
|
|
(def frozen-stress-data (nippy/freeze (nippy/stress-data {})))
|
|
=> #<byte[] [B@3253bcf3>
|
|
```
|
|
|
|
Deserialize it:
|
|
|
|
```clojure
|
|
(nippy/thaw frozen-stress-data)
|
|
=> {:bytes (byte-array [(byte 1) (byte 2) (byte 3)])
|
|
:nil nil
|
|
:boolean true
|
|
<...> }
|
|
```
|
|
|
|
Couldn't be simpler!
|
|
|
|
See also the lower-level [`freeze-to-out!`](https://taoensso.github.io/nippy/taoensso.nippy.html#var-freeze-to-out.21) and [`thaw-from-in!`](https://taoensso.github.io/nippy/taoensso.nippy.html#var-thaw-from-in.21) fns for operating on `DataOutput` and `DataInput` types directly.
|
|
|
|
# Encryption
|
|
|
|
> You may want to consider using Nippy with [Tempel](https://www.taoensso.com/tempel) for more comprehensive encryption options.
|
|
|
|
Nippy also gives you **dead simple data encryption**.
|
|
Add a single option to your usual freeze/thaw calls like so:
|
|
|
|
```clojure
|
|
(nippy/freeze (nippy/stress-data {}) {:password [:salted "my-password"]}) ; Encrypt
|
|
(nippy/thaw <encrypted-data> {:password [:salted "my-password"]}) ; Decrypt
|
|
```
|
|
|
|
There's two default forms of encryption on offer: `:salted` and `:cached`. Each of these makes carefully-chosen trade-offs and is suited to one of two common use cases. See [`aes128-encryptor`](https://taoensso.github.io/nippy/taoensso.nippy.html#var-aes128-encryptor) for a detailed explanation of why/when you'd want one or the other.
|
|
|
|
# Custom types
|
|
|
|
It's easy to extend Nippy to your own data types:
|
|
|
|
```clojure
|
|
(defrecord MyType [data])
|
|
|
|
(nippy/extend-freeze MyType :my-type/foo ; A unique (namespaced) type identifier
|
|
[x data-output]
|
|
(.writeUTF data-output (:data x)))
|
|
|
|
(nippy/extend-thaw :my-type/foo ; Same type id
|
|
[data-input]
|
|
(MyType. (.readUTF data-input)))
|
|
|
|
(nippy/thaw (nippy/freeze (MyType. "Joe"))) => #taoensso.nippy.MyType{:data "Joe"}
|
|
``` |