DR1N0 opened a new pull request, #3335:
URL: https://github.com/apache/tinkerpop/pull/3335
## Summary
This PR adds support for serializing custom types in gremlin-go, bringing it
to **feature parity with the Java driver** and completing the custom type
support that currently only includes deserialization. This implements the
official GraphBinary specification for custom types, enabling full round-trip
support for custom graph database types.
## Motivation
While gremlin-go supports deserializing custom types via
`RegisterCustomTypeReader()`, it lacks the corresponding serialization
capability. This creates an asymmetry where users can read custom types from
server responses but cannot write them in requests. The **Java driver already
has full custom type support** (both `CustomTypeSerializer` reader and writer),
and this PR brings gremlin-go to the same level.
## Changes
### New API Functions
- `RegisterCustomTypeWriter(valueType reflect.Type, typeName string, writer
CustomTypeWriter)` - Registers a custom serializer for a specific type
- `UnregisterCustomTypeWriter(valueType reflect.Type)` - Unregisters a
custom serializer
### New Types
- `CustomTypeWriter` - Function type for user-provided serialization
functions
- `CustomTypeInfo` - Struct holding type metadata (name and writer function)
### Implementation Details
- Added `customTypeWriter()` function to handle GraphBinary custom type
format (type_code=0x00, type_name, value)
- Modified `getType()` to detect registered custom types before checking
built-in types
- Modified `write()` to properly handle custom type format, matching the
Java implementation in `GraphBinaryWriter.java`:
```java
if (serializer instanceof CustomTypeSerializer) {
buffer.writeBytes(customTypeCodeBytes); // 0x00
writeValue(customTypeSerializer.getTypeName(), buffer, false);
customTypeSerializer.write(value, buffer, this);
}
```
### GraphBinary Format Compliance
The implementation follows the exact format used by Java's
`GraphBinaryWriter`:
- **Type code**: `0x00` (DataType.CUSTOM)
- **Type name**: UTF-8 string with length prefix
- **Value**: Custom-serialized data
This ensures **cross-driver compatibility** - custom types serialized by
gremlin-go can be deserialized by Java drivers and vice versa.
### Updated Files
- `gremlin-go/driver/serializer.go` - Added type definitions and
registration functions
- `gremlin-go/driver/graphBinary.go` - Added custom type writer
implementation and modified type detection
- `gremlin-go/driver/serializer_test.go` - Added test cases following
existing patterns
- `CHANGELOG.asciidoc` - Added changelog entry
## Test Coverage
Tests follow the same pattern as existing custom type reader tests:
- **Success case** in `TestSerializer`: "test serialized request message w/
custom type"
- **Failure case** in `TestSerializerFailures`: "test unregistered custom
type writer failure"
All tests pass:
```
=== RUN TestSerializer/test_serialized_request_message_w/_custom_type
--- PASS: TestSerializer/test_serialized_request_message_w/_custom_type
(0.00s)
=== RUN TestSerializerFailures/test_unregistered_custom_type_writer_failure
--- PASS:
TestSerializerFailures/test_unregistered_custom_type_writer_failure (0.00s)
```
## Use Case
This feature enables users to serialize custom graph database types (e.g.,
JanusGraph's `RelationIdentifier`) when sending requests to the server:
```go
import (
"bytes"
"encoding/binary"
"reflect"
)
// Define custom type writer
customWriter := func(value interface{}, buffer *bytes.Buffer) error {
// Custom serialization logic matching server expectations
return nil
}
// Register the writer
RegisterCustomTypeWriter(
reflect.TypeOf((*MyCustomType)(nil)),
"janusgraph.RelationIdentifier", // Must match server-side type name
customWriter
)
// Now MyCustomType instances can be serialized in requests
client.Submit("g.E().has('id', rid)", map[string]interface{}{"rid":
customValue})
```
## Benefits
1. **Feature Parity**: Brings gremlin-go to the same level as the Java driver
2. **GraphBinary Compliance**: Implements the official specification
3. **Cross-Driver Compatibility**: Custom types work across Java, Go, and
other GraphBinary drivers
4. **Complete Custom Type Support**: Enables full round-trip custom type
handling
## Backward Compatibility
This change is fully backward compatible - it only adds new functionality
without modifying existing APIs or behavior.
## References
- Java implementation:
`gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/GraphBinaryWriter.java`
- GraphBinary specification for custom types (DataType.CUSTOM = 0x00)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]