Remix.run Logo
dfabulich an hour ago

A stated goal of the API is to have "low ceremony"; this seems like a lot of ceremony.

    IO.println(JsonObject.of(Map.of("providers",
        JsonArray.of(List.of(JsonString.of("SUN"),
            JsonString.of("SunRsaSign"),
            JsonString.of("SunEC"))))));
There's gotta be a better way!

Surely there could be some way of creating a JsonArray of native Java Strings, Booleans, Doubles, and Integers without requiring clients to explicitly convert each value into a JsonValue. And why am I forced to convert a native List into a JsonArray just so I can make it the value of a JsonObject?

Why can't I write this?

   JsonObject.of(Map.of("providers", List.of("SUN", "SunRsaSign", SunEC"))));
nlitened an hour ago | parent | next [-]

There's a nice Java library called Clojure with a lightweight syntax if you need to work with data structures and concurrency in Java a lot:

    (println (json/generate-string {:providers ["SUN" "SunRsaSign" "SunEC"]}))
pron 24 minutes ago | parent | prev | next [-]

I'm not involved with the design of this API, but it seems to me that the issue on the JSON generation side (where you're complaining about ceremony) is feature creep. Creating the API you want on top of the proposed one is trivial (even in user code), but then where do you stop? If you have that conversion, it seems reasonable to also support, say, sets and records; maybe even enums.

Often, it's best to start with the minimum required, and then, as the API gets used in the field, see what the most valuable convenience methods to add on top.

cute_boi a minute ago | parent | prev | next [-]

Even Rust syntax is so much clean and better than this...

mechanicum 44 minutes ago | parent | prev | next [-]

You almost can, with Jackson:

  jshell> new ObjectMapper().valueToTree(Map.of("providers", List.of("SUN", "SunRsaSign", "SunEC")));
  $4 ==> {"providers":["SUN","SunRsaSign","SunEC"]}
(or was that the joke?)
dtech 27 minutes ago | parent | prev | next [-]

Java lacks the expressiveness to make it much better than this. There's a reason almost all the "replacement Java" languages add something to support DSLs, e.g. type safe builders in Kotlin [1]

The kotlin stdlib-adjacent json lib does it like this

   buildJsonObject {
     putJsonArray("providers") {
        add("SUN")
        add("SunRsaSign")
        add("SunEC")
     }
   }
[1] https://kotlinlang.org/docs/type-safe-builders.html
pron 17 minutes ago | parent [-]

That's not the reason. The question was about JSON generation from existing Java types, not about a DSL. Java JSON libraries offer similar conveniences (in fact, you can be much more sophisticated, clear, and convenient than the DSL you've shown), but this particular library, as explicitly described in the JEP, is not intended to be a general-purpose JSON library, of which Java already has several good and popular ones.

dtech 14 minutes ago | parent [-]

That's not what the person I replied to asked at all, arbitrary types weren't mentioned.

They literally asked why they couldn't write JsonObject.of(Map.of(...))

pron 13 minutes ago | parent [-]

And there's nothing in Java preventing that. In fact, it is trivial to implement that exact API on top of the API proposed in the JEP.

vlaaad an hour ago | parent | prev | next [-]

Yes, what's the point of JsonObject at all? Why JsonString when there is String? Why JsonArray when there is List? JDK only needs a function to convert from JSON format to the normal data structures it already has and back.

pron 31 minutes ago | parent | next [-]

Because JSON types don't cleanly map to Java types. For example, a JSON number could be an int, a long, a double, a BigInteger, or a BigDecimal. Which of them the Java code wants is not something you can deduce (most generally, you could represent all JSON numbers as BigDecimal, but that's not very convnient in Java code, so in most cases you'd want to convert that to a primitive type of your choosing anyway). A JSON array is heterogeneous, while Java code typically want to be homogeneous. Representing a JSON array as a `List<Object>` won't work because the conversion of the element types is ambiguous (e.g. numbers).

Hackbraten 4 minutes ago | parent [-]

Good point for parsing. However, the example is about serialization. What mapping ambiguity do you see there?

dtech 29 minutes ago | parent | prev [-]

It's pretty normal, almost all libs work this way. This way you can parse the JSON string into the matching data structure or print it into a string, and when building you can ensure it's valid JSON.

RedShift1 41 minutes ago | parent | prev [-]

minimal-json scratches this itch really well for me. Dead simple API. Unfortunately not maintained anymore, but I'm still using it, even for new projects, because it just works so well.