GFQL Wire Protocol Specification#
Introduction#
The GFQL Wire Protocol defines the JSON serialization format for GFQL queries, enabling:
Client-server communication
Query persistence and storage
Cross-language interoperability between Python, JavaScript, and other clients
Configuration-driven query generation
Design Principles#
Type Safety: Tagged dictionaries preserve type information
Self-Describing: Each object includes type metadata
Extensible: Schema supports future additions
Round-Trip Safe: Lossless serialization/deserialization
Protocol Overview#
Message Structure#
All GFQL wire protocol messages are JSON objects with a type field:
{
"type": "MessageType",
...additional fields...
}
Supported Message Types#
Chain: Complete query chainLet: DAG pattern with named bindingsChainRef: Reference to Let binding with optional chainRemoteGraph: Reference to remote datasetCall: Algorithm/transformation invocationNode: Node matcher operationEdge: Edge traversal operationPredicates:
GT,LT,EQ,IsIn,Between, etc.Temporal values:
datetime,date,time
Message Structure#
All GFQL wire protocol messages are JSON objects with a type field that identifies the message type. The protocol uses discriminated unions for polymorphic types.
Type Identification#
Each object includes a type field:
Operations:
"Node","Edge","Chain","Let","ChainRef","RemoteGraph","Call"Predicates:
"GT","LT","IsIn", etc.Temporal values:
"datetime","date","time"
This enables unambiguous deserialization and validation.
Operation Serialization#
Node Operation#
Python:
n({"type": "person", "age": gt(30)}, name="adults")
Wire Format:
{
"type": "Node",
"filter_dict": {
"type": "person",
"age": {
"type": "GT",
"val": 30
}
},
"name": "adults"
}
Edge Operation#
Python:
e_forward(
{"type": "transaction"},
hops=2,
source_node_match={"active": True},
name="txns"
)
Wire Format:
{
"type": "Edge",
"direction": "forward",
"edge_match": {
"type": "transaction"
},
"hops": 2,
"source_node_match": {
"active": true
},
"name": "txns"
}
Chain#
Python:
chain([
n({"id": "Alice"}),
e_forward({"type": "friend"}),
n({"status": "active"})
])
Wire Format:
{
"type": "Chain",
"chain": [
{
"type": "Node",
"filter_dict": {"id": "Alice"}
},
{
"type": "Edge",
"direction": "forward",
"edge_match": {"type": "friend"}
},
{
"type": "Node",
"filter_dict": {"status": "active"}
}
]
}
Let Operation#
Python:
let({
'persons': n({'type': 'Person'}),
'adults': ref('persons', [n({'age': ge(18)})])
})
Wire Format:
{
"type": "Let",
"bindings": {
"persons": {
"type": "Node",
"filter_dict": {"type": "Person"}
},
"adults": {
"type": "ChainRef",
"ref": "persons",
"chain": [{
"type": "Node",
"filter_dict": {
"age": {"type": "GE", "val": 18}
}
}]
}
}
}
ChainRef Operation#
Python:
ref('base_nodes', [
e_forward({'weight': gt(0.5)}),
n({'status': 'active'})
])
Wire Format:
{
"type": "ChainRef",
"ref": "base_nodes",
"chain": [
{
"type": "Edge",
"direction": "forward",
"edge_match": {"weight": {"type": "GT", "val": 0.5}}
},
{
"type": "Node",
"filter_dict": {"status": "active"}
}
]
}
RemoteGraph Operation#
Python:
remote(dataset_id='fraud-network-2024')
Wire Format:
{
"type": "RemoteGraph",
"dataset_id": "fraud-network-2024"
}
Call Operation#
Python:
call('compute_cugraph', {'alg': 'pagerank', 'damping': 0.85})
Wire Format:
{
"type": "Call",
"function": "compute_cugraph",
"params": {
"alg": "pagerank",
"damping": 0.85
}
}
Predicate Serialization#
Comparison Predicates#
{"type": "GT", "val": 100}
{"type": "LT", "val": 50.5}
{"type": "GE", "val": "2024-01-01"}
{"type": "LE", "val": true}
{"type": "EQ", "val": "active"}
{"type": "NE", "val": null}
Between Predicate#
{
"type": "Between",
"lower": 10,
"upper": 20,
"inclusive": true
}
IsIn Predicate#
{
"type": "IsIn",
"options": ["A", "B", "C"]
}
String Predicates#
{"type": "Contains", "pattern": "search"}
{"type": "Startswith", "pattern": "prefix"}
{"type": "Endswith", "pattern": "suffix"}
{"type": "Match", "pattern": "^[A-Z]+\\d+$"}
Null Predicates#
{"type": "IsNull"}
{"type": "NotNull"}
{"type": "IsNA"}
{"type": "NotNA"}
Temporal Check Predicates#
{"type": "IsMonthStart"}
{"type": "IsYearEnd"}
{"type": "IsLeapYear"}
Type Serialization#
Scalar Types#
"hello world" // string
42 // integer
3.14159 // float
true // boolean
null // null
Temporal Types#
DateTime#
{
"type": "datetime",
"value": "2024-01-15T10:30:00",
"timezone": "America/New_York" // Optional, defaults to "UTC"
}
Date#
{
"type": "date",
"value": "2024-01-15"
}
Time#
{
"type": "time",
"value": "14:30:00.123456"
}
Note: The timezone field is optional for DateTime values and defaults to “UTC” if omitted. This ensures consistent behavior across systems while allowing explicit timezone specification when needed.
Examples#
User 360 Query#
Python:
g.gfql([
n({"customer_id": "C123"}),
e_forward({
"type": "purchase",
"timestamp": gt(pd.Timestamp("2024-01-01"))
})
])
Wire Format:
{
"type": "Chain",
"chain": [
{
"type": "Node",
"filter_dict": {
"customer_id": "C123"
}
},
{
"type": "Edge",
"direction": "forward",
"edge_match": {
"type": "purchase",
"timestamp": {
"type": "GT",
"val": {
"type": "datetime",
"value": "2024-01-01T00:00:00",
"timezone": "UTC"
}
}
}
}
]
}
Cyber Security Pattern#
Python:
g.gfql([
n({"ip": is_in(["192.168.1.100", "192.168.1.101"])}),
e_forward(
edge_query="port IN [22, 23, 3389]",
to_fixed_point=True
),
n({"type": "server", "critical": True})
])
Wire Format:
{
"type": "Chain",
"chain": [
{
"type": "Node",
"filter_dict": {
"ip": {
"type": "IsIn",
"options": ["192.168.1.100", "192.168.1.101"]
}
}
},
{
"type": "Edge",
"direction": "forward",
"edge_query": "port IN [22, 23, 3389]",
"to_fixed_point": true
},
{
"type": "Node",
"filter_dict": {
"type": "server",
"critical": true
}
}
]
}
Best Practices#
Always include type fields: Every object must have a
typeUse ISO formats: Dates and times in ISO 8601
Handle timezones consistently: Include timezone for datetime values when precision matters (defaults to UTC)
Validate before sending: Use JSON Schema validation
Handle unknown fields: Ignore unrecognized fields for compatibility
See Also#
GFQL Language Specification - Language specification
Cypher to GFQL Python & Wire Protocol Mapping - Cypher to GFQL translation with wire protocol examples