wasm and grpc services talk to the Kernel through a shared contract. As a
service developer, you use the generated SDK for your chosen runtime rather
than building the wire format yourself; this page describes the shape of that
contract so you know what your service can expect and what it is responsible
for. static services do not use this protocol at all — see Static
services.
Two directions of communication
Startup: identity handshake
When the Kernel starts awasm or grpc service, the service performs a
short identity handshake: it confirms its name and version, and receives
whatever the Kernel needs to hand it, such as configured parameters. This
handshake does not, by itself, declare what the service serves.
While running: declaring transports and routes
After the handshake, the service tells the Kernel what it exposes by registering transports and routes through the Kernel’s side of the contract, and can add or remove them again at any point while it keeps running — not only once at startup. See Routes and transports for what a transport and a route each contain and how they relate. A transport or route that fails to register does not stop the service from running; it marks the servicedegraded while its other resources keep working.
Shutting down cleanly is symmetric: a service should remove routes before the
transport they depend on, and the Kernel forcibly cleans up anything left
behind when a service session ends, so a stopped or crashed service cannot
leave dead routes reachable.
Handling requests and events
Once a route is registered, matching HTTP requests and Socket.IO events are converted into typed messages and delivered to your service’s handlers:- An HTTP request carries the method, path, query, headers, body, and the authenticated user, if any. Your handler returns a status, headers, and a body. Request and response bodies are exchanged as complete messages, not a stream — keep payloads within the Kernel’s size limit, described on the HTTP transport page.
- A Socket.IO event carries the namespace, event name, sending socket, and the authenticated user, if any. Your handler can reply with one or more emit instructions, each targeting either one socket or the whole namespace.
Choose a runtime
Bothwasm and grpc services use the same contract; only how it crosses the
process boundary differs.
gRPC
You can implement agrpc service in any language with Protobuf and gRPC
support. The service runs as a separate process and communicates with the
Kernel over gRPC. Use your language’s Protobuf and gRPC tooling to generate or
implement the contract types, then set Type: grpc in the service manifest.
WASM
Arupa currently supports Go for WASM services. Use the Go SDK generated for the Arupa contract and compile the service to WASM. The WASM integration is based onknqyf263/go-plugin, which
generates Go interfaces and hides the raw WASM communication behind the SDK.
Follow the development model described in the
guide: define or consume the
contract, generate the Go bindings, implement the generated interface, and
compile the implementation as a WASM module. Set Type: wasm in the service
manifest.
The transport changes, but the message types and their meaning stay the same.
Choose the SDK and build process that match the Type in your manifest.
Use the generated SDK
Treat generated files as build artifacts. Do not edit them by hand. If you need a newly added message or field, regenerate the SDK from the matching schema and rebuild your service. SetContractVersion in info.yaml to the protocol version used by your
service. The version must be supported by the Kernel that will load the
package. The manifest version and the generated SDK should always be updated
together.
Using the generated SDK gives your service:
- typed request and response values;
- consistent serialization with the Kernel;
- runtime-specific communication handled for you; and
- one programming model regardless of
Type.
Keep your service compatible
When you consume a newer contract, remember that fields are identified by number, not only by name:- keep existing field numbers assigned to their original meaning;
- do not reuse the number of a removed field;
- add new fields with new numbers; and
- allow your service to ignore fields it does not need when the change is backward-compatible.
Typical development flow
- Choose
wasmorgrpcand use the matching generated SDK. - Implement the contract and your feature logic with the SDK types.
- Register the transports and routes your service provides, and keep them up to date if what the service exposes changes while it runs.
- Use Host bindings whenever your feature needs a Kernel-owned capability.
- Set the matching
ContractVersionin the service manifest. - Build and package the service, then load it with a Kernel that supports that contract version.