Type Registration
Type registration tells Fory how to identify and serialize your custom types. Registration is required for struct, enum, and extension types.
Why Register Types?
- Type Identification: Fory needs to identify the actual type during deserialization
- Polymorphism: When deserializing interface types, Fory must know which concrete type to create
- Cross-Language Compatibility: Other languages need to recognize and deserialize your types
Struct Registration
Register by ID
Register a struct with a numeric type ID for compact serialization:
type User struct {
ID int64
Name string
}
f := fory.New()
err := f.RegisterStruct(User{}, 1)
if err != nil {
panic(err)
}
ID Guidelines:
- IDs must be unique within your application
- IDs must be consistent across all languages for cross-language serialization
- Use the same ID for the same type in serializer and deserializer
Register by Name
Register a struct with a type name string. This is more flexible but has higher serialization cost:
f := fory.New()
err := f.RegisterNamedStruct(User{}, "example.User")
if err != nil {
panic(err)
}
Name Guidelines:
- Use fully-qualified names following
namespace.TypeNameconvention - Names must be unique and consistent across all languages
- Names are case-sensitive
Enum Registration
Go doesn't have native enums, but you can register integer types as enums:
Register by ID
type Status int32
const (
StatusPending Status = 0
StatusActive Status = 1
StatusComplete Status = 2
)
f := fory.New()
err := f.RegisterEnum(Status(0), 1)
Register by Name
err := f.RegisterNamedEnum(Status(0), "example.Status")
Extension Types
For types requiring custom serialization logic, register as extension types with a custom serializer:
f := fory.New()
// Register by ID
err := f.RegisterExtension(CustomType{}, 1, &CustomSerializer{})
// Or register by name
err = f.RegisterNamedExtension(CustomType{}, "example.Custom", &CustomSerializer{})
See Custom Serializers for details on implementing the ExtensionSerializer interface.
Registration Scope
Type registration is per-Fory-instance:
f1 := fory.New()
f2 := fory.New()
// Types registered on f1 are NOT available on f2
f1.RegisterStruct(User{}, 1)
// f2 cannot deserialize User unless also registered
f2.RegisterStruct(User{}, 1)
Registration Timing
Register types after creating a Fory instance and before any serialize/deserialize calls:
f := fory.New()
// Register before use
f.RegisterStruct(User{}, 1)
f.RegisterStruct(Order{}, 2)
// Now serialize/deserialize
data, _ := f.Serialize(&User{ID: 1, Name: "Alice"})
Nested Type Registration
Register all struct types in the object graph, including nested types:
type Address struct {
City string
Country string
}
type Person struct {
Name string
Address Address
}
f := fory.New()
// Register ALL struct types used in the object graph
f.RegisterStruct(Address{}, 1)
f.RegisterStruct(Person{}, 2)
Cross-Language Registration
For cross-language serialization, types must be registered consistently across all languages.
Using IDs
All languages use the same numeric ID:
Go:
f.RegisterStruct(User{}, 1)
Java:
fory.register(User.class, 1);
Python:
fory.register(User, type_id=1)
Using Names
All languages use the same type name:
Go:
f.RegisterNamedStruct(User{}, "example.User")
Java:
fory.register(User.class, "example.User");
Python:
fory.register(User, typename="example.User")
Rust:
#[derive(Fory)]
struct User {
id: i64,
name: String,
}
let mut fory = Fory::default();
fory.register_by_name::<User>("example.User")?;
Best Practices
- Register early: Register all types at application startup before any serialization
- Be consistent: Use the same ID or name across all languages and all instances
- Register all types: Include nested struct types, not just top-level types
- Prefer IDs for performance: Numeric IDs have lower serialization overhead than names
- Use names for flexibility: Names are easier to manage and less prone to conflicts
Common Errors
Unregistered Type
error: unknown type encountered
Solution: Register the type before serialization/deserialization.
ID/Name Mismatch
Data serialized with one ID or name cannot be deserialized if registered with a different ID or name.
Solution: Use consistent IDs or names across serializer and deserializer.
Duplicate Registration
Two types registered with the same ID will conflict.
Solution: Ensure unique IDs for each type.