Product Promotion
0x5a.live
for different kinds of informations and explorations.
GitHub - lectra-tech/koson: A concise and lightweight Kotlin DSL to build JSON objects and render their String representations
A concise and lightweight Kotlin DSL to build JSON objects and render their String representations - lectra-tech/koson
Visit SiteGitHub - lectra-tech/koson: A concise and lightweight Kotlin DSL to build JSON objects and render their String representations
A concise and lightweight Kotlin DSL to build JSON objects and render their String representations - lectra-tech/koson
Powered by 0x5a.live 💗
image:https://github.com/lectra-tech/koson/blob/main/image/koson-logo.png["Koson Logo", link="https://github.com/lectra-tech/koson", align="center"]
= Koson
image:https://github.com/lectra-tech/koson/actions/workflows/deploy.yml/badge.svg?branch=main["Deploy koson", link:"https://github.com/lectra-tech/koson/actions/workflows/deploy.yml"] image:https://codecov.io/gh/lectra-tech/koson/branch/main/graph/badge.svg["koson coverage", link="https://codecov.io/gh/lectra-tech/koson"] image:https://img.shields.io/maven-central/v/com.lectra/koson.svg["Maven Central", link="https://search.maven.org/search?q=g:com.lectra%20AND%20a:koson"] image:https://kotlin.link/awesome-kotlin.svg["awesome kotlin badge", link="https://github.com/KotlinBy/awesome-kotlin"]
A concise and lightweight Kotlin
DSL to build JSON
objects and render their String representations
Using no other dependency than Kotlin
Available on link:https://search.maven.org/search?q=g:com.lectra%20AND%20a:koson[Maven Central, window=_blank]
Now part of https://kotlin.link/[Awesome Kotlin] !
image:https://github.com/lectra-tech/koson/blob/main/image/live.gif["Live"]
== DSL
[source, Kotlin]
// for an empty object obj { }
// for an object obj { "attribute" to 42 "another" to true }
// for an empty array arr
// for an array arr["element", 12.345, null]
NOTE: Any combination of these elements is possible
== How to use
.Kotlin [source, Kotlin]
val obj = obj { "key" to 3.4 "anotherKey" to arr["test", "test2", 1, 2.433, true] "nullValue" to null "emptyObject" to obj { } "emptyArray" to arr "custom" to ZonedDateTime.now() }
println(obj) <1> println(obj.pretty()) <2>
.JSON output [source,json]
<1> {"key":3.4,"anotherKey":["test","test2",1,2.433,true],"nullValue":null,"emptyObject":{},"emptyArray":[],"custom":"2020-07-15T10:59:19.042965+02:00[Europe/Paris]"}
<2> { "key": 3.4, "anotherKey": [ "test", "test2", 1, 2.433, true ], "nullValue": null, "emptyObject": {
}, "emptyArray": [
], "custom": "2020-07-15T10:59:19.042965+02:00[Europe/Paris]" }
.Kotlin [source, Kotlin]
val array = arr[ "example", obj { "apple" to "pie" "key" to 3.14 "anotherKey" to arr["first", "second", 1, 2.433, true] } ]
println(array) <1> println(array.pretty()) <2>
.JSON output [source, json]
<1> ["example",{"apple":"pie","key":3.14,"anotherKey":["first","second",1,2.433,true]}]
<2> [ "example", { "apple": "pie", "key": 3.14, "anotherKey": [ "first", "second", 1, 2.433, true ] } ]
== Inlining obj
entries
If you wish so, you can inline multiple entries in obj
using Kotlin's optional statement separator ;
semicolon
[source, Kotlin]
obj { "key" to 3.4; "another" to true }
== Alternative arr
syntax
You can provide any Iterable
, thus Collection
to feed in an array arr
[source, Kotlin]
arr[listOf("element", 12.345, null)] arr[setOf("element", 12.345, null)]
== Pretty print
When using the pretty()
method on obj
or arr
, you can define the number of whitespaces used for tabulation.Default value is 2
.
[source,Kotlin]
// "compact", single line mode obj { ... }
// 2 whitespaces tabulation obj { ... }.pretty()
// 3 whitespaces tabulation arr[ ... ].pretty(3)
== Strong type constraints
- A JSON key (attribute) can only be of
Kotlin
typeString
(will render escaping"
,\
and\n
chars)
[NOTE]
In IntelliJ, a compilation error will appear, and code will be flagged as not reachable
image:https://github.com/lectra-tech/koson/blob/main/image/koson-typing.png["Koson Typing"]
- A JSON value of an obj { } or an arr[...] can be one of the following
Kotlin
or Koson DSL instances ** obj { } ** arr[...] ** arr (empty array) **String?
(will render escaping"
,\
and\n
chars) **Number?
**Boolean?
**null
**Any?
(will render using.toString()
, escaping"
,\
and\n
chars) **YourType : CustomKoson
, will render using.serialize()
. (See next section for details) ** rawJson("{...}") (will render as is). (See section below)
== Custom Types Serialization
If you don't want to rely on the default toString()
that would be used on an Any?
, you can provide an instance that implements the CustomKoson
interface.
You'll then need to override the serialize(): KosonType
method.
TIP: The KosonType
return type should either be an obj
or an arr
.Example [source,Kotlin]
class Person( val firstName: String, val lastName: String, val age: Int ) : CustomKoson { override fun serialize() = obj { "usualName" to "$firstName $lastName" "age" to age } }
== Raw Json
If you know what content will be rendered upfront, you should favor using DSL elements to build your Json.
However, sometimes you may need to include an external source of Json.
You can use the rawJson(validJson: String?)
method to do so.
[source,Kotlin]
obj { "rawContent" to rawJson(externalJsonSource()) }
[WARNING]
You need to ensure the parameter String?
is a valid Json (by format), otherwise the generated Json will not be valid.
Beware that rendering will not escape "
, \
and \n
chars, on purpose.
NOTE: pretty()
will not work on rawJson
Strings, however toString()
will inline provided content
== Runtime prerequisites
Kotlin
Java
1.8 or later
== Build prerequisites
Java
8 or later
[source]
./mvnw package
== Benchmarks
Benchmarks have been conducted with the https://openjdk.java.net/projects/code-tools/jmh/[jmh] OpenJDK tool.Benchmark project can be found under benchmarks
folder.
Two tests were done with the same objects and arrays
- Rendering a big object (String representation)
- Rendering a big array (String representation)
Koson
was put side to side with one of the most popular JSON builder for Java
: https://github.com/stleary/JSON-java[JSON-java]
Testing environment : 3.3 GHz Intel Core i5-6600, 4 cores, VM version: OpenJDK 11.0.1, 64-Bit Server VM, 11.0.1+13
.Score in operations/second (throughput mode), higher = better |=== |Benchmark |Score |Error |Units
|BigObject - JSON-java |17120,661 |± 45,741 |ops/s
|BigObject - Koson |17433,982 |± 372,361 |ops/s
|BigObject (pretty) - JSON-java |8902,486 |± 19,417 |ops/s
|BigObject (pretty) - Koson |10252,254 |± 71,377 |ops/s
|BigArray - JSON-java |15272,946 |± 139,435 |ops/s
|BigArray - Koson |14816,130 |± 132,266 |ops/s
|BigArray (pretty) - JSON-java |7744,935 |± 41,067 |ops/s
|BigArray (pretty) - Koson |8607,388 |± 31,712 |ops/s |===
To run the tests locally with java 8 or later, do
[source]
cd benchmarks mvn package java -jar target/benchmarks.jar
Kotlin Resources
are all listed below.
Made with ❤️
to provide different kinds of informations and resources.