Logo

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

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

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 type String (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.

Resources

listed to get explored on!!

Made with ❤️

to provide different kinds of informations and resources.