Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure encode Joda DateTime with ring-json

With the following app:

; src/webapp/core.clj
(ns webapp.core
  (:require [compojure.core :refer [defroutes GET]]
            [ring.middleware.json :as mid-json]
            [clj-time.jdbc]))

(defn foo [request]
  {:body {:now (org.joda.time.DateTime/now)}})

(defroutes routes
  (GET "/foo" [] foo))

(def app
  (-> routes
      (mid-json/wrap-json-response)))

Hitting the /foo endpoint gives me this error:

com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class org.joda.time.DateTime: 2017-10-21T03:38:16.207Z

Is there a simple way to get ring-json to encode the DateTime object? Do I have to write my own middleware to convert it to e.g. a string first? If so, how would I do that? (I've never written ring middleware before).

My project.clj has these dependencies FYI:

[[org.clojure/clojure "1.8.0"]
 [org.clojure/java.jdbc "0.6.1"]
 [ring/ring-jetty-adapter "1.4.0"]
 [compojure "1.4.0"]
 [ring/ring-json "0.4.0"]
 [clj-time "0.14.0"]]
like image 570
Jacob O'Bryant Avatar asked Oct 21 '17 03:10

Jacob O'Bryant


Video Answer


1 Answers

If you're using Cheshire to generate JSON, you can extend its protocol to handle serialization then it should "just work":

(extend-protocol cheshire.generate/JSONable
  org.joda.time.DateTime
  (to-json [dt gen]
    (cheshire.generate/write-string gen (str dt))))
like image 189
Taylor Wood Avatar answered Sep 22 '22 06:09

Taylor Wood