Skip to content

Data Binding (kbars-kxs / kbars-yamlkt)

The kbars core module renders against a KpaStruct context — a kPointer adapter interface, not a JSON or YAML library. The two format modules exist purely to bridge parsed JSON or YAML into that shape, via one extension function each on KbEnvironment.Companion:

Module Format Entry point
kbars-kxs JSON KbEnvironment.fromJson()
kbars-yamlkt YAML KbEnvironment.fromYaml()

Both re-export kbars as a transitive api dependency (see Adding a dependency), and both take the same three parameters: the source text, an optional clock for the default now environment property, and a configure DSL lambda for registering transforms and properties.

Which one do I pick?

  • Your data already arrives as a JSON string (an HTTP response body, a config file, a message payload) → kbars-kxs.
  • Your data arrives as YAML (a config file, most CI/tooling manifests) → kbars-yamlkt.
  • You already have a KpaStruct built some other way (hand-built, or via a different kPointer adapter) → skip both format modules and call KbEnvironment.create() directly with that struct.

Nothing stops a project from depending on both — they don't conflict, since they only differ in how they populate the same KpaStruct context.

Feeding raw JSON or YAML text

This is the direct case: you have the text on hand, and want a KbEnvironment in one call.

// kbars-kxs
val env = KbEnvironment.fromJson("""{"name":"Alice"}""")

// kbars-yamlkt
val env = KbEnvironment.fromYaml(
  """
  name: Alice
  """.trimIndent()
)

Both throw if the text doesn't parse to an object/map at the top level (IllegalArgumentException for fromJson, SerializationException for fromYaml) — kBars templates always render against a struct, so a bare JSON array or YAML scalar at the document root isn't a valid context.

Feeding a @Serializable class

Neither fromJson nor fromYaml accepts a @Serializable instance directly — there's no KbEnvironment.from(myObject) overload. Instead, encode the instance to text with the same serialization library, then hand that text to fromJson / fromYaml exactly as above:

@Serializable
data class Order(val id: String, val total: Double)

val order = Order(id = "A-100", total = 42.50)

// kbars-kxs — kotlinx.serialization.json
val env = KbEnvironment.fromJson(Json.encodeToString(order))

// kbars-yamlkt — net.mamoe.yamlkt
val env = KbEnvironment.fromYaml(Yaml.encodeToString(order))

This round-trip through text (rather than a direct object-graph walk) keeps both format modules to a single, narrow bridge — JsonElement/YamlElement to KpaStruct — instead of a second one for arbitrary @Serializable types.

Rendering, once you have an environment

From here on, both modules behave identically to the core-only path described in Rendering, in three steps:

val template = KbTemplate.create("Hello {{ /name }}!")

println(template.render(env)) // "Hello Alice!"

Where to next

  • Usage Overview — the three-module split and adding a dependency.
  • Environment Properties — the @env namespace and the default now property both fromJson / fromYaml seed.
  • Templates — text, delimiters, comments, raw blocks, whitespace trimming.