Skip to content

Martini YAML Functions

Overview

Martini's built-in YAML functions let you read, write, and convert YAML data directly inside services and workflows—without external libraries or custom parsing logic. They handle everything from quick data model serialization to streaming large YAML files, keeping your services lean and memory-efficient.

What You Will Learn

  • How to serialize a data model into a YAML string
  • How to parse YAML from strings, input streams, and readers into data models
  • How to produce formatted YAML output using writers and printers
  • How to stream large YAML datasets one node at a time using input cursors
  • How to build and write YAML documents incrementally using output cursors

When To Use This

Use Martini YAML functions when you need to:

  • Export configuration data — Serialize application or infrastructure configuration into YAML for storage, deployment, or downstream services
  • Ingest YAML payloads — Deserialize YAML documents from file imports, APIs, or queue-based integrations into data models
  • Process large YAML files — Stream large YAML documents incrementally to reduce memory usage during imports or transformations
  • Generate YAML output on the fly — Build structured YAML documents incrementally as a workflow or service populates data

Prerequisites

YAML Conversion Functions

Martini's YAML conversion functions translate between data models and YAML text in both directions. Whether you are preparing a YAML payload to send downstream or parsing an incoming document into a structured model, these functions cover the full round-trip.

Getting Started with YAML Data Model Conversion

The most direct way to produce a YAML string from a data model is modelPropertyToYamlString. Supply a populated data model, and the function serializes its properties into a YAML string ready for use.

Example — Serializing a data model to YAML:

Suppose you have a data model deploymentConfig with these properties set at runtime:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
deploymentConfig {
    environment = staging
    region = us-east-1
    resources {
        replicas = 3
        cpuLimit = 2.5
        autoScale = true
    }
    version = 1.4.2
}

Call the function with the modelProperty parameter set to deploymentConfig:

1
modelPropertyToYamlString(modelProperty: deploymentConfig)

Expected result: The function returns the following YAML string:

1
2
3
4
5
6
7
environment: staging
region: us-east-1
resources:
  replicas: 3
  cpuLimit: 2.5
  autoScale: true
version: 1.4.2

Example — Parsing a YAML string back into a data model:

To go the other direction, call yamlStringToModelProperty, which returns a wrapped object; map that object to a typed data model whose property names match the YAML keys so you can access the parsed values.

1
2
yamlStringToModelProperty(yamlString: myYamlString)
// Map the returned object to a typed data model whose property names match the YAML keys

Expected result: After mapping, the target data model is populated with the properties and values from the YAML string.

YAML Conversion Function Reference

The following table lists the available YAML conversion functions and their primary uses:

Function Primary Use
modelPropertyToYamlString(...) Serialize a data model into a YAML string
yamlStringToModelProperty(...) Parse a YAML string into a wrapped data model object
inputStreamToModelProperty(...) Parse YAML content from an InputStream into a wrapped data model object
readerToModelProperty(...) Parse YAML content from a Reader into a wrapped data model object
writeYaml(...) Stream YAML output directly to a Writer
printYaml(...) Generate formatted, human-readable YAML output using an IndentPrinter

How YAML Type Mapping Works

Knowing how Martini converts property types between data models and YAML helps you anticipate the output of each conversion.

Data model to YAML — type mapping rules:

When serializing a data model to YAML, each property type maps to a YAML value type as follows:

Data model property type YAML value type
String YAML scalar string (value)
Whole number (Integer, Long) YAML integer scalar (3)
Decimal number (Float, Double, BigDecimal) YAML float scalar (2.5)
Boolean YAML boolean scalar (true / false)
Nested data model YAML mapping (key: value block)
Array property YAML sequence (- item list)

Null properties are excluded by default

When serializing a data model to YAML, properties with null values are omitted unless the includeNulls parameter is set to true or the property is marked as Required. A property marked as Required is always serialized, even if its value is null. For meta-property configuration details, see Accessing Individual Property Configuration.

YAML to data model — type mapping rules:

When parsing YAML into a data model, the resulting property types are derived from the YAML value:

YAML value type Data model property type
YAML string String
YAML integer Integer
YAML float Double
YAML boolean Boolean
YAML mapping Nested data model
YAML sequence Array property; element type inferred from the first element in the sequence
YAML null String

Null and empty value handling

Values that represent absence in YAML are not preserved as null types; they are stored as strings:

  • null"null"
  • Blank value (fieldName:) → ""
  • ~"~"

YAML Conversion Benefits and Use Cases

YAML conversion functions remove the need to write manual serialization or parsing code, cutting development time and eliminating the risk of producing malformed output. Common real-world applications include:

  • Configuration management: Read an incoming YAML configuration payload from a file using inputStreamToModelProperty, validate or transform its fields, then serialize the result back to YAML with modelPropertyToYamlString.
  • Structured output: Produce a human-readable YAML document from a data model using printYaml with an IndentPrinter for export or logging.
  • Message-driven processing: Deserialize YAML messages arriving from a queue or broker into typed data models before passing them to downstream processing steps.

Troubleshooting YAML Conversion Issues

Problem Detection Cause Fix
Properties missing from serialized YAML output Expected fields do not appear in the YAML output Properties with null values are excluded from serialization by default Set includeNulls to true to include all null properties, or mark specific properties as Required to always serialize them.
Numeric values have unexpected types after parsing Numeric field resolves as an unexpected property type YAML integers map to Integer and floats map to Double Confirm the YAML source uses the correct numeric format for the target property type
YAML parsing fails during conversion Conversion function throws a parse or syntax exception YAML input is malformed or uses unsupported syntax Validate the YAML structure and confirm the payload is syntactically correct

YAML Streaming Cursor Functions

Martini's YAML cursor functions let you read and write large YAML documents one node at a time, so you can work with datasets of any size without memory pressure. For a general introduction to cursors in Martini, see Martini Cursors.

Getting Started with YAML Input Cursors

Use openYamlFileInputCursor to step through selected nodes in a YAML file without reading the entire file into memory at once.

Example workflow structure using openYamlFileInputCursor:

flowchart LR
    s[...]
    a["`**Function Node:** Open YAML file input cursor and map to _myCursor_`"]
    b["`**Repeat Node:** Iterate over _myCursor_`"]
    c["`Process the current _myCursor_ entry`"]
    d[...]
    s --> a --> b -- each --> c
    b -- then --> d

Map the cursor to an array property (here, myCursor), then use a Repeat Node with myCursor as its input array. Each iteration delivers one matched YAML node.

Expected result: Each iteration provides a nodeName identifying which YAML key was matched and a cursorRecord containing the value for that node.

How YAML Input Cursor Streaming Works

Martini offers two functions for opening YAML input cursors:

  • openYamlFileInputCursor(...) — Opens a cursor over a YAML file at a specified file path.
  • openYamlStreamingInputCursor(...) — Opens a cursor over a YAML InputStream.

Both functions accept a yamlNodeNames parameter—a list of YAML key names to target during the scan. The cursor advances sequentially through the document and yields only nodes whose names appear in yamlNodeNames.

How each cursor iteration works:

Each iteration returns a data model entry with two properties:

  • nodeName — The matched key name from yamlNodeNames
  • cursorRecord — The value at that key (a scalar or a nested data model)

Example — Iterating over selected nodes:

Given this YAML input:

1
2
3
4
5
6
7
service: authentication
endpoint:
  path: /api/v1/auth
  method: POST
  rateLimit: 100
  secure: true
description: Handles token-based authentication

With yamlNodeNames set to ["service", "endpoint"]:

  • Iteration 1: nodeName = "service", cursorRecord = "authentication"
  • Iteration 2: nodeName = "endpoint", cursorRecord contains a data model with properties path, method, rateLimit, and secure
  • The cursor ends—"description" is not in yamlNodeNames and is skipped.

Targeting a root-level YAML sequence:

If the YAML root is a sequence (a top-level list with no key name), add the special value $yamlRoot to yamlNodeNames:

1
openYamlFileInputCursor(filePath: '/config/services.yaml', yamlNodeNames: ['$yamlRoot'])

Each cursor record corresponds to one entry in the root sequence. For example, a root sequence containing three mappings yields three iterations—one cursorRecord per entry.

Targeting nested fields directly:

Node names can reference nested keys by name. For example, specifying "rateLimit" instead of "endpoint" yields:

  • nodeName = "rateLimit", cursorRecord = 100

Parent and Child Node Matching

If yamlNodeNames includes both a parent key (for example, "endpoint") and one of its child keys (for example, "rateLimit"), the cursor returns the parent's record and does not separately yield the child. To retrieve only the child value, remove the parent key from yamlNodeNames.

How YAML Output Cursors Work

The openYamlOutputCursor(...) function opens a write cursor that builds a YAML document progressively and writes it to a configured destination, such as a StringBuffer or OutputStream.

Once the cursor is open, append data models to it. Each appended model contributes its properties as YAML keys or sequence entries in the final document.

Example workflow structure — Writing a YAML sequence:

flowchart LR
    s[...]
    a["`Prepare _environments_ data model array`"]
    b["`**Function Node:** Open YAML output cursor and map to _myOutputCursor_`"]
    c["`**Repeat Node:** Iterate over _environments_ with _myOutputCursor_ as the output array`"]
    d["`**Map Step**: Map the current _environments_ entry to the current _myOutputCursor_`"]
    e[...]
    s --> a --> b --> c -- each --> d
    c -- then --> e

Assume you are writing to /output/environments.yaml and you have an environments data model array already populated with two entries:

  • environment: staging, replicas: 2
  • environment: production, replicas: 5

The output cursor returned by the function is mapped to myOutputCursor.

In the Repeat Node, environments is the input array and myOutputCursor is the output array. For each iteration, the current environments entry is mapped to the current myOutputCursor—this appends the entry to the cursor and writes it to the destination as a YAML sequence entry.

Expected result: /output/environments.yaml contains a YAML sequence with two entries:

1
2
3
4
- environment: staging
  replicas: 2
- environment: production
  replicas: 5

Writing individual YAML keys (non-sequence output):

Output cursors are not limited to sequences. To write individual key-value pairs, append a data model with the desired properties directly to the cursor—without a Repeat Node or Iterate Step. For example, appending a model with status = "active" produces status: active in the YAML output.

To append data models to a cursor outside of a Repeat node or Iterate step, see Service Functions for cursor interaction functions.

YAML Streaming Benefits and Use Cases

Streaming cursors are the right tool whenever the size of a YAML dataset is unknown or potentially large. Processing one node at a time keeps memory usage flat regardless of document size.

Real-world applications include:

  • Large configuration files: Stream a sizeable infrastructure YAML file and apply per-record validation or transformation without loading it all at once.
  • ETL pipelines: Read from a YAML source stream, transform each record, and write the results to a YAML output file in a single service.
  • Selective extraction: Pull only the specific named keys you need from a complex YAML document without parsing the full structure.

Troubleshooting YAML Cursor Issues

Problem Detection Cause Fix
Fewer cursor records than expected Iteration ends before all matching nodes are processed A listed node name is a child of another listed name; the cursor returns the parent's record instead of separately surfacing the child Remove the parent key from yamlNodeNames and keep only the child name, or vice versa
Root-level sequence yields no records Cursor returns zero iterations on a YAML file whose root is a list The root sequence has no key name and $yamlRoot was not added to yamlNodeNames Add "$yamlRoot" to yamlNodeNames to target the unnamed root sequence
Output YAML is invalid after writing The final YAML file fails validation or cannot be parsed Print configuration wraps a root-level YAML sequence in incorrect mapping syntax Review and correct the print configuration on openYamlOutputCursor to match the intended YAML structure

Helpful Resources