-
Notifications
You must be signed in to change notification settings - Fork 0
Serialization
In Vyra, the serializer you choose IS the wire format.
Unlike systems that wrap binary payloads inside base64 strings or hand-roll custom binary codecs, Vyra uses a single pure serializer to encode both the outer Message envelope and your inner application objects.
When Vyra sends a message, it passes the entire Message envelope and your application object to the configured serializer. The serializer encodes the entire structure in a single pass, producing a clean byte array for transport.
Because your application object is placed directly in the payload field, JSON serializers embed it as native, clean JSON:
{
"messageId": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"correlationId": "a1c7d200-5e3e-4fa0-8bb2-3d849cf1a111",
"source": "api-gateway-1",
"kind": "REQUEST",
"destination": "billing-service",
"messageType": "invoice.create",
"timestamp": 1716382000000,
"payload": {
"customerId": "cust-88",
"items": [
{ "sku": "ITEM-1", "quantity": 2, "price": 49.99 }
]
},
"headers": {}
}-
Inspectable: you can monitor traffic directly in
redis-cliusingMONITORorLRANGE req:billing-service 0 -1. - No base64 overhead: no 33% base64 size penalty or extra string allocations.
- Single pass: envelopes and payloads are serialized together in a single pass.
Vyra provides official serializer modules in separate artifacts:
| Serializer | Factory method | Format | Characteristics | Best for |
|---|---|---|---|---|
| Jackson JSON | JacksonSerializer.jackson() |
JSON | Human-readable JSON, broad Java ecosystem support. | Default choice for development and general microservices. |
| Jackson Smile | JacksonSerializer.smile() |
Binary (Smile) | 30% to 50% smaller than JSON, fast parsing, Jackson API. | High-throughput services where bandwidth or broker memory matters. |
| Jackson CBOR | JacksonSerializer.cbor() |
Binary (CBOR) | RFC 8949 standard binary format, fast parsing. | Environments requiring standard IETF binary formats. |
| Gson JSON | GsonSerializer.gson() |
JSON | Lightweight JSON alternative with minimal dependencies. | Applications already centered around Google Gson. |
Add the chosen serializer to your build.gradle.kts:
// For Jackson (JSON, Smile, and CBOR)
implementation("com.marioded.vyra:vyra-jackson:0.1.0")
// Or for Gson
// implementation("com.marioded.vyra:vyra-gson:0.1.0")Then configure it on the Vyra builder:
import com.marioded.vyra.jackson.JacksonSerializer;
// Human-readable JSON
Vyra vyraJson = Vyra.builder()
.transport(transport)
.serializer(JacksonSerializer.jackson())
.build();
// High-performance binary Smile
Vyra vyraSmile = Vyra.builder()
.transport(transport)
.serializer(JacksonSerializer.smile())
.build();Important
Every node communicating on the same transport MUST use the same serializer format.
Because the serializer controls the entire wire envelope:
- A node using
JacksonSerializer.smile()cannot decode a message sent by a node usingJacksonSerializer.jackson(). - If a node receives an unparseable message from an incompatible serializer, Vyra drops the message safely and logs a warning with troubleshooting hints. The application node will never crash.
When a message arrives over the wire:
- The transport reads raw bytes.
- The serializer decodes the outer
Messageenvelope. At this stage, thepayloadis represented as a generic tree structure (e.g., aMaporJsonNode). - Core looks up the target Java class from your registered
messageType. - Core calls
Serializer.convert(payload, targetClass)to transform the generic tree into your strongly-typed Java record.
Jackson and Gson implementations perform this conversion in-memory using optimized tree-to-object conversions without re-serializing.
In Google Gson, all numbers in untyped JSON structures default to Double. For integers larger than
-
Tip: if you use Gson with large IDs (e.g., Twitter Snowflakes or 64-bit unsigned longs), model them as
StringorBigDecimal. - Jackson is unaffected by this issue.
If you configure a custom naming strategy on your ObjectMapper (such as PropertyNamingStrategies.SNAKE_CASE), it will apply to the envelope fields as well as your payload:
{ "message_id": "...", "correlation_id": null, "message_type": "...", ... }This works as long as all nodes share the same serializer configuration (uniform network constraint).
- Learn how to deploy in Transports.
- Review the complete Best practices for production deployments.
Vyra documentation