Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mechanism to enable Jackson Features #95

Open
poernahi opened this issue Feb 11, 2019 · 2 comments
Open

Add mechanism to enable Jackson Features #95

poernahi opened this issue Feb 11, 2019 · 2 comments

Comments

@poernahi
Copy link

Currently, the API does not expose a way to enable jackson's encoder/decoder features. It looks like the only way to do this is through the :mapper key in [:formats "application/json" :decoder-opts] or [:formats "application/json" :encoder-opts].

Use case example:
For compatibility, I would like to enable com.fasterxml.jackson.core.JsonParser.Feature/ALLOW_UNQUOTED_CONTROL_CHARS

I think some change in jsonista is required to support this.

I propose adding an option key, maybe named features, where library consumer can pass a map of features. jsonista can then call .configure on each item. Or the features could be translated to clojure keywords.

Example:

(ns project.middleware.formats
  (:require [muuntaja.core :as m])
  (:import (com.fasterxml.jackson.core JsonParser$Feature)))

(def instance
  (m/create
    (-> m/default-options
        (update-in [:formats "application/json" :decoder-opts]
          (partial merge {:features {JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS true}})))))

;; in jsonista
(defn ^ObjectMapper object-mapper
  "..."
  ([options]
    (doto (ObjectMapper.)
      ;; ...
      (#(doseq [[k v] (:features options)] (.configure % k v))))))

I can create PR if the proposal is blessed. Thanks!

@ikitommi
Copy link
Member

There seem to be at least the following type of features, that all can be configured in the ObjectMapper:

I think it would be good to be able to set any of these easily.

option 1: document how to do this the Java-way

  • add the features to the ObjectMapper returned via the j/object-mapper, e.g.
(def mapper
  (doto (j/object-mapper)
    (.enable JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS)))
  • mount the mapper to Muuntaja via :mapper option:
(def muuntaja
  (m/create
    (assoc-in
      m/default-options
      [:formats "application/json" :opts]
      {:mapper mapper})))
  • enjoy

option 2: make it easier

  • add a new configuration key for all features, :features, which takes a sequence of features
(j/object-mapper {:features [JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS ...]})

(def muuntaja
  (m/create
    (assoc-in
      m/default-options
      [:formats "application/json" :opts]
      {:features [JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS ...]})))

option 3: all-clojure

  • map all the options as clojure keywords for even easier config
  • naming the features, maybe: :json-parser/allow-unquoted-control-chars?
  • the mapping between clojure & java should be automatic: new features -> just work. I would guess this would need helper functions like (j/parser-features), (j/serialization-features), ... which would list all the possible values via Class scanning. Best would be if one could also get the descriptions so it would return a map of key -> description. I guess that would need a javadoc scraper...
(j/object-mapper {:features #{:json-parser/allow-unquoted-control-chars ...}})

(def muuntaja
  (m/create
    (assoc-in
      m/default-options
      [:formats "application/json" :opts]
      {:features #{:json-parser/allow-unquoted-control-chars ...}})))

thoughts?

@poernahi
Copy link
Author

poernahi commented Feb 12, 2019

I thought about option 1 but it will silently ignore other keys in :opts, possibly causing bugs?
For example, I think the sample code above will ignore the default {:decode-key-fn true}.

https://github.com/metosin/muuntaja/blob/master/modules/muuntaja/src/muuntaja/format/json.clj#L13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants