Format System¶
Mycel uses map[string]interface{} as its internal data representation. The format system handles serialization and deserialization at protocol boundaries: incoming requests, outgoing responses, and calls to external APIs.
Supported Formats¶
| Format | Content-Type | Implementation |
|---|---|---|
json |
application/json |
encoding/json (stdlib) |
xml |
application/xml |
encoding/xml (stdlib) |
The default format is json unless overridden.
Configuration¶
On Connectors¶
Setting format on a connector applies it as the default for all operations on that connector.
connector "legacy_api" {
type = "http"
base_url = "https://legacy.example.com"
format = "xml"
}
connector "xml_server" {
type = "rest"
port = 3000
format = "xml"
}
On Flows¶
Setting format on a from or to block overrides the connector-level default for that specific flow.
flow "bridge" {
from {
connector = "api"
operation = "POST /convert"
format = "xml"
}
to {
connector = "modern_api"
format = "json"
}
}
On Steps¶
Individual steps can also specify a format independently.
Auto-Detection¶
Mycel attempts to detect the correct format automatically when it is not explicitly configured.
- REST server (incoming requests): format is inferred from the
Content-Typerequest header - HTTP client (responses): format is inferred from the
Content-Typeresponse header
Resolution priority (highest to lowest):
- Format explicitly set on the flow or step
- Format detected from
Content-Typeheader - Format set on the connector
- Default:
json
XML Mapping Rules¶
When XML is decoded, it is converted to a map[string]interface{} that Mycel can process normally. The following rules apply:
| XML construct | Map representation |
|---|---|
| Element name | map key |
| Text content | string value |
| Child elements | nested map |
| Repeated elements | []interface{} slice |
| Attributes | keys prefixed with @ |
| Text content alongside attributes | #text key |
Example¶
<product id="42" category="widgets">
<name>Widget</name>
<price currency="USD">19.99</price>
<tag>sale</tag>
<tag>new</tag>
</product>
Decoded to:
{
"@id": "42",
"@category": "widgets",
"name": "Widget",
"price": {
"@currency": "USD",
"#text": "19.99"
},
"tag": ["sale", "new"]
}
The resulting map is available in transforms and step references as normal:
transform {
output.product_id = input.product["@id"]
output.product_name = input.product.name
output.currency = input.product.price["@currency"]
output.price = input.product.price["#text"]
}
Extensibility¶
Custom codecs can be registered at startup to add support for additional formats.
A codec must implement the following interface:
type Codec interface {
Encode(v interface{}) ([]byte, error)
Decode(data []byte, v interface{}) error
ContentType() string
Name() string
}
Once registered, the custom format name can be used in any format field in HCL configuration.