| title | Native Serialization |
|---|---|
| sidebar_position | 2 |
| id | native |
| license | Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. |
Go native serialization is the Go-only wire mode selected with fory.WithXlang(false). Use it
when every writer and reader is a Go service and the payload should follow Go's type system instead
of the portable xlang type system.
Use Cross-Language Interoperability, the default Go mode, when bytes must be read by Java, Python, C++, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, Kotlin, or another non-Go Fory implementation.
Use native serialization when:
- A payload is produced and consumed only by Go applications.
- The data model uses Go-specific behavior such as native
int/uint, nil slices, nil maps, pointers, interfaces, or Go-only dynamic values. - You want faster serialization and smaller size, and every reader uses the same struct schema as the writer.
- You want compatible schema evolution for Go-only rolling deployments without committing to a cross-language type mapping.
- You are using Go fast serializers for structs that never leave Go.
package main
import "github.com/apache/fory/go/fory"
type Order struct {
ID int64
Amount float64
}
func main() {
f := fory.New(fory.WithXlang(false))
if err := f.RegisterStruct(Order{}, 100); err != nil {
panic(err)
}
data, err := f.Serialize(&Order{ID: 1, Amount: 42.5})
if err != nil {
panic(err)
}
var decoded Order
if err := f.Deserialize(data, &decoded); err != nil {
panic(err)
}
}Reuse a configured Fory instance. The default instance owns reusable buffers and is not
thread-safe; use the thread-safe wrapper for concurrent goroutines.
import (
"github.com/apache/fory/go/fory"
"github.com/apache/fory/go/fory/threadsafe"
)
f := threadsafe.New(fory.WithXlang(false), fory.WithTrackRef(true))
_ = f.RegisterStruct(Order{}, 100)Native serialization defaults to compatible mode. Keep that default when Go-only services roll independently:
writer := fory.New(fory.WithXlang(false))
reader := fory.New(fory.WithXlang(false))Compatible mode writes schema metadata so readers can tolerate added, removed, or reordered fields when field names or explicit field IDs remain compatible. See Schema Evolution.
For faster serialization and smaller size, set WithCompatible(false) only when
every reader and writer always uses the same Go struct schema.
Register structs before serializing them. Prefer explicit numeric IDs for long-lived payloads:
_ = f.RegisterStruct(Order{}, 100)
_ = f.RegisterStruct(LineItem{}, 101)Name-based registration is useful when ID coordination is harder:
_ = f.RegisterStructByName(Order{}, "example.Order")If you register without stable IDs, every writer and reader must make the same registration choices.
Native serialization keeps Go data in Go-native form:
- Primitive numeric types, including Go-native
intanduint. - Structs with exported fields.
- Slices, arrays, maps, and Fory sets.
- Pointers and nil values, including nil slices and maps.
- Interfaces and dynamic values when registered serializers can resolve their concrete types.
- Time values such as
time.Timeandtime.Duration. - Fast serializers.
Use Supported Types for the full type surface and xlang mapping details.
Enable reference tracking for shared object identity or cycles:
f := fory.New(fory.WithXlang(false), fory.WithTrackRef(true))
type Node struct {
Value int32
Next *Node `fory:"ref"`
}Disable reference tracking for value-shaped data. It is faster and smaller, but repeated pointers deserialize as independent values and cyclic graphs are unsupported.
The default Fory instance reuses its internal buffer. Copy serialized bytes if they must outlive
the next serialization call:
data, _ := f.Serialize(value)
stable := append([]byte(nil), data...)The thread-safe wrapper copies bytes before returning them. For high-throughput single-threaded
code, serialize into a caller-owned ByteBuffer:
buf := fory.NewByteBuffer(nil)
err := f.SerializeTo(buf, value)
data := buf.GetByteSlice(0, buf.WriterIndex())
_ = err
_ = data- Reuse
Foryor the thread-safe wrapper instead of constructing a Fory instance per request. - Use
WithCompatible(false)only when every reader and writer always uses the same Go struct schema and wants faster serialization and smaller size. - Register structs with explicit numeric IDs.
- Disable reference tracking unless the graph requires identity or cycles.
- Copy returned bytes only when the data must survive the next serialization call.
| Requirement | Use native serialization | Use xlang serialization |
|---|---|---|
| Go-only payloads | Yes | Optional |
| Non-Go readers or writers | No | Yes |
Go-native int, uint, nil slice/map |
Yes | Limited |
| Same-schema compact payloads | Yes | No |
| Compatible schema evolution by default | Yes | Yes |
| Portable type mapping across languages | No | Yes |
The writer is using native serialization. Rebuild it with fory.WithXlang(true) and align type
registration with every peer.
Native serialization defaults to compatible mode. Keep that default when struct definitions can differ.
Use native serialization for Go-only payloads that must preserve Go nil slice/map semantics. Cross-language schemas should model nullability explicitly.
The default Fory instance reuses its buffer. Copy the byte slice or use threadsafe.New(...).
- Cross-Language Interoperability - Cross-language Go payloads
- Configuration - Go options
- Type Registration - Struct and enum registration
- References - Shared and circular references
- Schema Evolution - Compatible mode