- Human-readable
- Self-describing format (don’t need to know the underlying type)
- Easy interop with JavaScript
- Less efficient size and (de)serialization
- Compact, binary format that’s efficient for serialized data size
- Need to know data format or have a schema to deserialize data
- Strict and canonical binary representation
- Fast and less overhead in most cases
Overriding Serialization Protocol Default
The result and parameter serialization can be opted into separately, but all parameters must be of the same format (can’t serialize some parameters as borsh and others as JSON). An example of switching both the result and parameters to borsh is as follows:result_serializer(borsh) annotation will override the default result serialization protocol from JSON to borsh and the serializer(borsh) annotations will override the parameter serialization.
Example
A simple demonstration of getting a Borsh-serialized, base64-encoded value from a unit test: The following snippet shows a simple function that takes this value from a frontend or CLI. Note: this method doesn’t have a return value, so the#[result_serializer(borsh)] isn’t needed.
Note that this is using this simple struct:
To call this with NEAR CLI, use a command similar to this:
JSON wrapper types
To help with serializing certain types to JSON which have unexpected or inefficient default formats, there are some wrapper types innear_sdk::json_types that can be used.
Because JavaScript only supports integers to value 2^53 - 1, you will lose precision if deserializing the JSON integer is above this range. To counteract this, you can use the I64, U64, I128, and U128 in place of the native types for these parameters or result to serialize the value as a string. By default, all integer types will serialize as an integer in JSON.
You can convert from U64 to u64 and back using std::convert::Into, e.g.
.0:
u variants to upper-case U variants using U64(...) and U128(...):
serde serialize and deserialize respectively. All of these types just override the JSON format and will have a consistent borsh serialization and deserialization as the inner types.
Base64VecU8
Another example of a type you may want to override the default serialization of isVec<u8> which represents bytes in Rust. By default, this will serialize as an array of integers, which is not compact and very hard to use. There is a wrapper type Base64VecU8 which serializes and deserializes to a Base-64 string for more compact JSON serialization.
Example here: