clojure/data.json

repository·master·Indexed 20 days ago

https://github.com/clojure/data.json

A JSON parser and generator for Clojure that converts between JSON and Clojure data structures. It is compliant with the JSON specification and has no external dependencies. Provides functions for string-based conversion (json/read-str, json/write-str), stream-based processing (json/read, json/write), and optional key and value transformation via :key-fn and :value-fn.

Tokens
1.2K
Snippets
4
Records
5
Agent score
19%

What's inside data.json

  1. Install data.json

    master

    You can add data.json to your project using various Clojure dependency management tools. The project follows a MAJOR.MINOR.PATCH versioning scheme and aims for non-breaking changes by introducing new names rather than breaking existing ones.

    ;; CLI/deps.edn
    org.clojure/data.json {:mvn/version "2.5.2"}
    
    ;; Leiningen
    [org.clojure/data.json "2.5.2"]
    
    ;; Maven
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>data.json</artifactId>
      <version>2.5.2</version>
    </dependency>
  2. Read and write JSON using streams

    master

    For handling large datasets or streaming data, use the following functions instead of string-based versions:

    • json/read: Reads JSON directly from a java.io.Reader.
    • json/write: Writes JSON directly to a java.io.Writer.
  3. Transform map values with :value-fn

    master

    You can provide a :value-fn to transform map values. The function is called with two arguments: [key value] and must return the updated value.

    Important Constraints:

    • :value-fn only works on maps (JSON objects). If your root data structure is a vector or another type, you must pre- or post-process it using tools like clojure.walk.
    • Execution Order during Reading: The value-fn is called after the key-fn has processed the key.
    • Execution Order during Writing: The value-fn is called before the key-fn processes the key.
    ;; Reading: value-fn receives the processed key
    (defn my-value-reader [key value]
      (if (= key :date)
        (java.sql.Date/valueOf value)
        value))
    
    (json/read-str "{\"number\":42,\"date\":\"2012-06-02\"}" 
                   :value-fn my-value-reader 
                   :key-fn keyword) 
    ;;=> {:number 42, :date #inst "2012-06-02T04:00:00.000-00:00"}
    
    ;; Writing: value-fn is called before key-fn
    (defn my-value-writer [key value]
      (if (= key :date)
        (str (java.sql.Date. (.getTime value)))
        value))
    
    (json/write-str {:number 42, :date (java.util.Date. 112 5 2)}
                    :value-fn my-value-writer
                    :key-fn name) 
    ;;=> "{\"number\":42,\"date\":\"2012-06-02\"}"
  4. Transform map keys with :key-fn

    master

    You can provide a :key-fn to transform map keys during both reading and writing operations.

    • When reading: The function is applied to the JSON keys to produce Clojure keys (e.g., converting strings to keywords).
    • When writing: The function is applied to Clojure map keys to produce JSON keys (e.g., converting keywords to uppercase strings).
    ;; Convert JSON string keys to keywords during read
    (json/read-str "{\"a\":1,\"b\":2}" :key-fn keyword)
    ;;=> {:a 1, :b 2}
    
    ;; Convert Clojure keys to uppercase strings during write
    (json/write-str {:a 1 :b 2} :key-fn #(.toUpperCase %))
    ;;=> "{\"A\":1,\"B\":2}"
    
    ;; Prefix keys during read
    (json/read-str "{\"a\":1,\"b\":2}" :key-fn #(keyword "com.example" %))
    ;;=> {:com.example/a 1, :com.example/b 2}
  5. Convert Clojure data to and from JSON strings

    master

    Use json/write-str to convert Clojure data structures into JSON strings, and json/read-str to parse JSON strings back into Clojure data.

    Note: These operations are not symmetric; converting Clojure data into JSON is lossy (e.g., map keys are converted to strings).

    (ns example
      (:require [clojure.data.json :as json]))
    
    ;; Write to string
    (json/write-str {:a 1 :b 2})
    ;;=> "{\"a\":1,\"b\":2}"
    
    ;; Read from string
    (json/read-str "{\"a\":1,\"b\":2}")
    ;;=> {"a" 1, "b" 2}