Json dsl


#1

Here is the best JSON DSL I've been able to come up with for Kotlin so far:

JSON:

``

{
  “a” : “b”,
  “c” : [ 1, 2.34, “abc”, false ],
  “e” : {
  “f” : 30,
  “g” : 31
  }
}

Kotlin:

val j = json {   obj("a", "b",   "c", array(1, 2.34, "abc", false),   "e", obj("f", 30, "g", 31)   ) }

Can anyone think of a more elegant solution?

#2

I think mappings is more easy to coding, and looks better.

val j = json {   obj("a" to "b",   "c" to array(1, 2.34, "abc", false),   "e" to obj("f" to 30, "g" to 31)   ) }

extension to - part of standart library https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/Standard.kt#L48


#3

In my experience, such DSL don't combine well with each other. The task is in fact not to build something really close json in syntax, but allow to programmatically build json easily.

json {   for(item in items) {            if (item.property == 0)            obj("a" to "${item.value}")            else            obj("c" to array // oops, how do I map item.values collections into this array?   } }

Ability to compose DSL with other DSLs and with language constructs is much more important than syntactic beauty, I think :)


#4

The task is in fact not to build something really close json in syntax, but allow to programmatically build json easily.

Absolutely, and that was my goal. Before the DSL, creating inline JSON documents was pretty awkward:

val o = JsonObject().put("a", "b").put("c", JsonArray(1, 2, 3))...

The DSL makes this a little easier to write and read, at least, as far as the Kotlin type system allows.

As for composing DSL’s, I’m not sure what you mean. In my experience, it’s pretty rare to want to combine completely unrelated DSL’s, do you have an example in mind?


#5

I dont get why

val j = json {
  items map {it.property == 0 ? obj(“a” to it.value) : obj(“c” to it.values) }
}

wouldnt be programmatically easy.


#6

It's very easy, I was objecting to my initial (non-DSL) version, where you had to instantiate all the objects explicitly.

I like the “to” approach, it differentiates arrays from objects more clearly.


#7

My reply was to Ilya, look at the indentation. But now I realize that he was probably suggesting to use kotlin's groovy style builder.

Even if json has no need for typing, even if your approach is essentialy what we happilly do when writting json in javascript, kotlin’s groovy style builder syntax may do a few things more naturally.
Here is my uncompiled guess at a json expressed with a kotlin groovy style builder.

json{
  obj{
  prop(“a”, 1)
  for((k,v) in map1){
          prop(k, v)
  }
  for((k,v) in map2){
          if(v){

           prop(k, v)
          }
  }
  }
}

I dont know what he meant by DSL composition.