Skip to main content
Calling an operation is different from calling a mutation in one important way: every request carries a request key, a stable identity for that business request. The key is what lets you retry safely after a lost response without applying the change twice.
src/cancelOrder.ts
Here client is any Bijection client, such as a BijectionHttpClient or a BijectionReactClient, and api.orders.cancel is the generated reference for the operation.

Operation references

In the generated api object, an operation is an operation reference rather than an ordinary function reference. It carries the operation’s contract: its object type, target, arguments and result. Each operation is served by companion functions that the backend generates from your one declaration: operationFunctionReference(operation, companion) returns the function reference for one companion. The argument helpers build the matching request envelope and include the contract the reference was generated with:
  • operationInvocationArgs(operation, requestKey, args) for invoke and recover
  • operationPreviewArgs(operation, args) for preview
  • operationStatusArgs(operation, invocationId) for status
The tools you already use present an operation as one entry, not five functions. See CLI and console.

Request keys

A request key identifies one business request. Its rules are simple:
  • Use a new key for a new request. Two requests with different keys are two different business requests, even if their arguments are equal.
  • Reuse the key to retry. If a response is lost, submit the same key and the same arguments again. The backend returns the original acceptance instead of running preparation a second time.
  • Keep the arguments with the key. Submitting a key that was already accepted with different arguments is refused with OperationRequestConflict.
A key is scoped to the caller, the component, the operation and the deployment.
A lost or unreadable response does not mean the request failed. Never replace the key because you did not receive an answer: recover it instead.

The acceptance receipt

invoke returns once the request’s local changes have committed: A receipt is evidence of local acceptance only. The external calls the request submitted are delivered afterwards; follow them with status.

Previewing an operation

A preview runs the operation’s preparation on the current data, validates the result the same way acceptance does, reports what it found, and discards everything. It uses no request key and accepts, reserves and sends nothing.
src/previewCancel.ts
The report contains: is_executable is advice, not a promise. When the request is actually submitted, every check runs again on the data as it is then. A preview needs the operation’s read and preview grants. Submitting needs invoke as well.
Previewing an operation that submits external calls is in beta.

Recovering a request

If you do not know whether a request was accepted, ask recover with the same key and arguments. It is a query, and it never runs preparation or contacts an external system.
src/recoverCancel.ts
recover returns either { kind: "accepted", ...receipt } or { kind: "absent" }. An absent answer does not authorize a new key: the original request may still be in flight. Submitting the same key again is always safe.

Following a request

status reports where an accepted request’s external calls stand. It is a query, so you can subscribe to it and it updates as outcomes are recorded:
src/OrderStatus.tsx
The status contains the receipt fields except local_result, and:
  • external_calls: for each call, its delivery outcome and its publication (whether the confirmed result has been published back into your tables). See External calls.
  • summary: counts of calls by outcome, including pending, unknown and publication_pending.
  • review: whether the request is held for a person, described below.
You can also look up a status by the original request key and arguments instead of the invocation ID.

Review state

A request can be held until someone acts. review says why, and who must act: The state is derived from the request’s retained records each time it is read. It is never inferred from how long a request has been waiting. A decision itself is made by your own review operation, through access rules and approvals.

Calling operations from server code

From an action or a mutation, call the companions with ctx.runMutation and ctx.runQuery, exactly as a client would:
bijection/assistant.ts
Deriving the key from something stable, such as the suggestion being applied, means a retried action submits the same request instead of a new one. When one operation is invoked inside another transaction, its acceptance is tentative until the outer transaction commits.

Revising a blocked request

Revising a request is in beta.
An accepted external call stays bound to the integration command definition it was accepted under. If that command’s definition or its governing rule changes before the call was ever sent, the call is blocked instead of being delivered under a contract nobody accepted. The revise companion re-admits such calls under the definitions the destination publishes now. It takes { invocation_id, expected_contract } and requires the invoke grant. It only applies to calls that were never held for delivery; if any call of the request was, the whole revision is refused with OperationWasHeld. It reports which calls moved (restamped) and which already matched (unchanged).

Errors

Operation companions refuse with a BijectionError whose data is { kind: "operation_error", code }. The most common codes: A refusal from your own preparation, such as a stale revision, is your own BijectionError and reaches the caller unchanged.