Caller and receiver

In Graftcode, Caller and Receiver name the two services in an integration:

  • the Caller is the calling service — your application that needs to invoke behavior elsewhere;
  • the Receiver is the called service — your module whose public methods are the contract.

Both sides are user-written. You own the service business logic on each side. Graftcode does not generate your domain code, database access, or deployment. It removes the integration layer you would otherwise maintain between those services — HTTP clients, route handlers, hand-designed DTOs, and custom SDKs.

Generated Graft between user-written Caller and Receiver services

What you write vs what is generated

Caller (calling service)Between the servicesReceiver (called service)
You writeApplication or service business logic; when to call; retries, auth policy, and operational handlingModule or class library with an intentional public surface
Generated for youGraft — typed package that mirrors the Receiver's callable surface
Operated / hostedYour runtime and deploymentHypertube inside the Graft; Gateway when configured for remote executionYour module, loaded in-process or hosted by Gateway

The Graft is the only integration artifact the Caller installs. It is produced from the Receiver's public interface, not from your private implementation.

Caller — the calling service

The Caller is your service that:

  • decides when and with what arguments to invoke the Receiver;
  • installs the generated Graft from Vision or the public registry;
  • sets GraftConfig (for example host and stateless) before the first call;
  • handles latency, failures, retries, and authorization appropriate to the deployment.

At the call site your code looks like a normal method invocation on generated types. Under that surface, the Graft initializes Hypertube, serializes the command, and routes it to the configured execution path — in-memory or through Gateway. You do not hand-write that plumbing.

Receiver — the called service

The Receiver is your module — typically a plain class library or package — whose supported public methods form the callable surface.

You write the implementation. Gateway hosts the module for remote execution (or the same module loads in-process for in-memory mode). Callers never receive your source code; they receive a Graft generated from the public surface.

Keep transport types, ORM models, secrets, and framework handles off the public surface. See Public surface vs implementation.

Integration layers Graftcode replaces

Without Graftcode, connecting two services usually means designing and maintaining integration code on at least one side:

Hand-written integrationWith Graftcode
REST or OpenAPI client, URLs, and HTTP verbsGenerated Graft method call
Request and response DTOs separate from domain modelsTypes derived from the Receiver surface
Custom SDK or fetch wrapper per consumer languagePackage manager install from Vision or registry
Different client code for local vs remoteSame call site; GraftConfig selects execution mode

Graftcode cuts out that middle layer. The Caller service stays focused on business logic; the Graft carries the contract.

When some clients must stay on REST, see Use Graftcode alongside an existing REST API.

One service, two roles

Caller and Receiver describe one invocation direction, not fixed product roles. The same codebase can:

  • act as a Receiver when it exposes a module through Gateway;
  • act as a Caller when it installs another team's Graft.

A modular monolith can host multiple Receivers in one process while one component Calls another through an in-memory Graft — still the same Caller / Receiver / Graft model.

Under the hood

For readers who need runtime detail:

Caller side (inside the Graft): resolve configuration, obtain a runtime context, build a command for the target member, deserialize the result or surface an error.

Receiver side: accept the command on the enabled execution path, dispatch to the hosted member, return the serialized response.

Remote execution still crosses a process or network boundary. "Looks like a method call" does not mean local failure semantics — plan for timeouts, partial failures, and version skew like any distributed call.

Continue