@BinaryCall
Overview
@BinaryCall defines a request-response operation executed against a @BinaryService.
It maps a TypeScript method to a remote action executed inside a binary process, using the Binary Protocol.
From the developer perspective, it behaves like an async function call.
What a Binary Call Represents
A Binary Call is:
- A single request sent to a binary process
- Matched to exactly one response
- Asynchronous and promise-based
- Isolated from the Node.js runtime
A Binary Call is not:
- A stream
- A background job
- A fire-and-forget message
- A direct function invocation
Each call is a remote procedure call over stdin/stdout.
Declaring a Binary Call
A binary call is declared by decorating a method with @BinaryCall.
import { BinaryService, BinaryCall } from "@open-core/framework/server";
@BinaryService({ name: "crypto" })
export class CryptoBinary {
@BinaryCall("hashPassword")
hash(password: string): Promise<{ hash: string }> {
return null as any;
}
}
This declaration:
- Binds the method to a protocol
action - Transforms the method into a remote call
- Replaces the method body at runtime
The method body is never executed.
Action Mapping
The string passed to @BinaryCall defines the action name sent to the binary.
@BinaryCall("hashPassword")
This results in a protocol request:
{
"id": "...",
"action": "hashPassword",
"params": [...]
}
If no name is provided, the method name is used by default.
Parameters and Serialization
Method parameters are serialized positionally and sent as params.
@BinaryCall()
compare(a: string, b: string): Promise<boolean> {}
Produces:
{
"action": "compare",
"params": ["a", "b"]
}
Rules:
- Parameters must be JSON-serializable
- Functions and class instances are not allowed
- Validation is responsibility of the binary
Return Values
The return type of the method represents the expected result field.
@BinaryCall()
sign(data: string): Promise<string> {}
Binary response:
{
"status": "ok",
"result": "signature"
}
Type safety exists only at the TypeScript boundary. The binary must enforce correctness.
Error Propagation
If the binary responds with status: "error":
- The promise is rejected
- The error message is propagated
- Optional error codes are preserved
{
"status": "error",
"error": {
"message": "Invalid key"
}
}
From JavaScript, this behaves like a thrown exception.
Timeouts
Each call is executed with a timeout.
If the binary does not respond in time:
- The call fails
- The promise is rejected
- The service may be restarted
Timeouts protect the server from blocked processes.
Execution Guarantees
- Calls are matched using a unique
id - Responses are resolved exactly once
- Late or duplicate responses are ignored
- Calls are isolated per Binary Service instance
There is no implicit retry.
Relation to Other Decorators
-
@BinaryServiceDefines where the call is executed. -
@BinaryCallDefines how a request is sent and resolved. -
@BinaryEventIs unrelated to calls and does not affect responses.
Calls and events can coexist but are handled independently.
Mental Model
A @BinaryCall is best understood as:
- A remote function invocation
- Executed outside the JS runtime
- With strict request/response semantics
If the binary crashes, the call fails. If the protocol breaks, the call fails. This is intentional.
Summary
@BinaryCall provides:
- Clear request-response semantics
- Strong isolation
- Predictable failure behavior
- A clean async API for native code
If you need a value back from a binary, this is the tool.