Create a custom JSON marshaller

Gradle setup

implementation group: "org.http4k", name: "http4k-core", version: ""
implementation group: "org.http4k", name: "http4k-format-jackson", version: ""

Custom auto-mapping JSON configurations

http4k declares an extended set of "primitive" types which it can marshall out of the box - this includes the various http4k primitives (Uri, Status), as well as a bunch of common types from the JDK such as the DateTime classes and Exceptions. These primitives types cannot be marshalled as top-level JSON structures on their own so should be contained in a custom wrapper class before transmission.

You can declare your own custom marshaller by reimplementing the Json instance and adding mappings for your own types - either uni or bi-directional.

This ability to render custom types through different JSON marshallers allows API users to provide different "views" for different purposes - for example we may wish to hide the values of some fields in the output, as below:


package guide.howto.create_a_custom_json_marshaller

import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.KotlinModule
// this import is important so you don't pick up the standard auto method!
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.ConfigurableJackson
import org.http4k.format.asConfigurable
import org.http4k.format.text
import org.http4k.format.withStandardMappings

object MyJackson : ConfigurableJackson(KotlinModule()
    // declare custom mapping for our own types - this one represents our type as a simple String
    .text(::PublicType, PublicType::value)
    // ... and this one shows a masked value and cannot be deserialised (as the mapping is only one way)
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

data class PublicType(val value: String)
data class SecretType(val value: String) {
    override fun toString(): String {
        return "****"

data class MyType(val public: PublicType, val hidden: SecretType)

fun main() {
        Response(OK).with(<MyType>().toLens() of MyType(PublicType("hello"), SecretType("secret")))

    /** Prints:

    HTTP/1.1 200 OK
    content-type: application/json; charset=utf-8