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]

Reply via email to