Can I have a body lens which produces pretty forma...
# http4k
m
Can I have a body lens which produces pretty formatted JSON (on server side)?
This seems to work (with GSON):
Copy code
val prettyGson = GsonBuilder().setPrettyPrinting().create()
val prettyJsonBody = Body.string(ContentType.APPLICATION_JSON, "pretty JSON").map(
        {
            prettyGson.fromJson(it, JsonElement::class.java)
        },
        {
            prettyGson.toJson(it)
        }
).toLens()
There is a
pretty
thing here: https://github.com/http4k/http4k/blob/master/http4k-format/core/src/main/kotlin/org/http4k/format/Json.kt#L67 but I am not sure how it is supposed to be used 🤔
s
You can do it by creating a custom
ConfigurableGson
and using the
auto
from it. Here's a full example:
Copy code
import CustomGson.auto
import com.google.gson.GsonBuilder
import org.http4k.core.Body
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.core.with
import org.http4k.format.ConfigurableGson
import org.http4k.format.asConfigurable
import org.http4k.format.withStandardMappings


data class MyDataClass(val foo: String, val bar: String)

fun main() {
    val lens = Body.auto<MyDataClass>().toLens()

    val response = Response(OK).with(lens of MyDataClass("foo", "bar"))

    println(response)
}

object CustomGson : ConfigurableGson(
    GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()
        .asConfigurable()
        .withStandardMappings()
        .done()
)
This prints:
Copy code
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8

{
  "foo": "foo",
  "bar": "bar"
}
m
Right. I only want this for some endpoints though, not all.
s
You can still do this with import aliases:
Copy code
import CustomGson.auto as prettyAuto
(then use
Body.prettyAuto
to create the special lens)
You can then mix and match different Json Config
d
Adding in pretty printing just for browser usage seems a bit odd. Maybe you could make it an option for the entire API so that you get pretty or compact for all endpoints when you configure your server? (ie. switch out the GSON instance)
a
Note: If you use a swagger UI, it will pretty-print the JSON for you, without having to customize marshallers