-
Notifications
You must be signed in to change notification settings - Fork 174
Interoperability considerations
There are some considerations to ensure interoperability.
When you think both of interoperability and versioning, you have to consider that which is better to use array or map to represent object. The MessagePack de facto standard is array (as RPC arguments, Java implementations, etc), so you should use array for serialization (it is default option). You should also specify field order, however, with DataMemberAttribute
or MessagePackMemberAttribute
(the latter is preferred). This is because there are no specifications for ordering of enumerated fields/properties, so it will depend runtime behavior without explicit indication, then portability as well as forward comatibility might be lost. In addition, you cannot insert field(s) between existent ones because it breaks backward compatibility of the data. You should consider inheritance for data type because base type field/property addition may break compatibility because new member must have the order which have been owned by the derived type member.
In contrust, When you used map for serialization method, ordering is not a matter, and it is easier to ensure compatibility because you only watch member names among type hierarchy never conflict. There are some drawbacks, however. First, serialization/deserialization is slower than array due to string key treatment. In addition, deserialization performance is not good because it have to lookup name table to deserialize members. Second, serialized data size will be improved for keys.
If you like to use map instead of array, you can specify SerializationContext.SerializationMethod
to SerializationMethod.Map
.
When you serialize objects using default settings or SerializationMethod.Array
, you should specify [MessagePackMember]
attribute to the fields/properties. Compilers and Reflection API do NOT guarantee the order of the members, so the order of serialized member will be undefined unless you specify them by [MessagePackMember]
attribute.
Note: You should notice that whether your compiler/runtime truely guarantee its field order in runtime. Some platforms do, and some platforms (such as Java) do not. As you know, unless it is guaranteed by its specification, the behavior is implementation specific, so it will be changed in the future version or patch.
As of 0.6.0-b4, msgpack bin
and ext
type are implicitly used in packing, but it required to specify explicitly compatibility options before 0.6.0-b4. In addition, you might want to disable these types to interop with legacy unpackers. The compatibility options are exposed by PackerCompatibilityOptions
enum, which is apeared in a parameter of Packer.Create
factory method and SerializationContext.CompatibilityOptions
property.
Unfortunately, there are no consensus abput interoperable datetime format in binary because of many considerations including:
- When is the epoc best? Many *nix friendly systems use 1970, but it looks unnatural.
- How about the precision? More precision can represent more precise time, but it loses compactness or/and range.
- How about the range? Do you really use the datetime of 30,000 years before/after now?
- There are various eras in the world. Although it looks reasonable to use Gregorian calendar, some people might not be able to accept.
If you are intersted in this issue, you can post the issue for entire msgpack protocol in [https://github.com/msgpack/msgpack/issues].
For the present(as of 0.6.0), MessagePack for CLI uses 64/96bit representation for DateTime
and DateTimeOffset
using their native binary representations. It can prevent unexpected data loss, but it loses interoperability and backward compatibility. In past, they are serialized as unix epoc time format, it was more interoperable but caused data loss accidents. You can still switch the behavior to accomplish interoperability or backward compatibility with setting SerializationContext.DefaultDateTimeConversionMethod
.
You should know that binary representations of strings, dates, times, big integers/big decimals are different on each platforms. Unfortunately, MessagePack prefer simplicity (it improves connetability because more developers easy to implement bindings), so there are no built in types for above. However, there are de facto for these types, and default serializers of MessagePack for CLI respect them. For more information for de facto standards and default serializer specifications, see Built-in Serializer Specifications.