Skip to main content

Triggers

The ballerina/grpc connector enables you to expose Ballerina services as gRPC servers. A grpc:Listener listens on a TCP port for incoming gRPC requests, and a grpc:Service defines the remote functions that implement the RPC methods declared in your .proto file. The auto-generated stub code from bal grpc creates typed Caller objects used within service callbacks to send responses back to clients.

Three components work together:

ComponentRole
grpc:ListenerListens on a specified port for incoming gRPC requests over HTTP/2 and dispatches them to attached services.
grpc:ServiceDefines remote functions that implement the RPC methods. Attached to a grpc:Listener to handle incoming calls.
grpc:CallerProvided inside service callbacks for streaming and bidirectional RPCs to send responses, errors, and complete the stream back to the client.

For action-based operations, see the Action Reference.


Listener

The grpc:Listener establishes the connection and manages event subscriptions.

Configuration

The listener supports the following connection strategies:

Config TypeDescription
ListenerConfigurationConfiguration record for the gRPC server listener.

ListenerConfiguration fields:

FieldTypeDefaultDescription
hoststring"0.0.0.0"The hostname the server binds to.
secureSocketListenerSecureSocket?()SSL/TLS configuration for the server endpoint. Set this to enable TLS or mutual TLS.
timeoutdecimal120Period of time in seconds that a connection waits for a read/write operation. Use 0 to disable.
maxInboundMessageSizeint4194304The maximum permitted inbound message size in bytes. Default is 4 MB.
maxHeaderSizeint8192The maximum permitted header size in bytes. Default is 8 KB.
reflectionEnabledbooleanfalseEnable gRPC server reflection support.

Initializing the listener

Basic listener on a port:

import ballerina/grpc;

listener grpc:Listener grpcListener = new (9090);

Listener with TLS:

import ballerina/grpc;

listener grpc:Listener grpcListener = new (9090,
secureSocket = {
key: {
certFile: "/path/to/server.crt",
keyFile: "/path/to/server.key"
}
}
);
Generating certificates

For instructions on generating certificates using keytool, see Keystores and Truststores.

Listener with mutual TLS:

import ballerina/grpc;

listener grpc:Listener grpcListener = new (9090,
secureSocket = {
key: {
certFile: "/path/to/server.crt",
keyFile: "/path/to/server.key"
},
mutualSsl: {
verifyClient: grpc:REQUIRE,
cert: "/path/to/ca.crt"
}
}
);

Service

A grpc:Service is a Ballerina service attached to a grpc:Listener. Each remote function in the service corresponds to an RPC method defined in the .proto file. The function signature varies by communication pattern: unary methods accept and return messages directly, server streaming methods return a stream, client streaming methods accept a stream, and bidirectional streaming methods accept both a Caller and a stream.

Callback signatures

FunctionSignatureDescription
Unary RPCremote function <MethodName>(MessageType request) returns ResponseType|errorHandles a simple request-response RPC. Accepts a single message and returns a single response.
Server Streaming RPCremote function <MethodName>(MessageType request) returns stream<ResponseType, grpc:Error?>|errorHandles a server streaming RPC. Accepts a single request and returns a stream of responses.
Client Streaming RPCremote function <MethodName>(stream<MessageType, grpc:Error?> clientStream) returns ResponseType|errorHandles a client streaming RPC. Accepts a stream of client messages and returns a single response.
Bidirectional Streaming RPCremote function <MethodName>(TypedCaller caller, stream<MessageType, grpc:Error?> clientStream) returns error?Handles a bidirectional streaming RPC. Receives a typed Caller for sending responses and a stream of client messages.
note

The service name (e.g., "RouteGuide") and remote function names (e.g., GetFeature) must match the service and RPC method names in your .proto file. The @grpc:ServiceDescriptor annotation binds the service to the auto-generated proto descriptor.

Full usage example

import ballerina/grpc;
import ballerina/io;
import ballerina/time;

listener grpc:Listener ep = new (9090);

@grpc:ServiceDescriptor {descriptor: ROOT_DESCRIPTOR, descMap: getDescriptorMap()}
service "RouteGuide" on ep {

// Unary RPC: returns a single Feature for a given Point
isolated remote function GetFeature(Point point) returns Feature|error {
foreach Feature feature in FEATURES {
if feature.location == point {
return feature;
}
}
return {location: point, name: ""};
}

// Server streaming RPC: returns a stream of Features within a Rectangle
remote function ListFeatures(Rectangle rectangle) returns stream<Feature, grpc:Error?>|error {
int left = int:min(rectangle.lo.longitude, rectangle.hi.longitude);
int right = int:max(rectangle.lo.longitude, rectangle.hi.longitude);
int top = int:max(rectangle.lo.latitude, rectangle.hi.latitude);
int bottom = int:min(rectangle.lo.latitude, rectangle.hi.latitude);

Feature[] selectedFeatures = from var feature in FEATURES
where feature.name != ""
where feature.location.longitude >= left
where feature.location.longitude <= right
where feature.location.latitude >= bottom
where feature.location.latitude <= top
select feature;

return selectedFeatures.toStream();
}

// Client streaming RPC: receives a stream of Points, returns a RouteSummary
remote function RecordRoute(stream<Point, grpc:Error?> clientStream) returns RouteSummary|error {
Point? lastPoint = ();
int pointCount = 0;
int featureCount = 0;
int distance = 0;

decimal startTime = time:monotonicNow();
check clientStream.forEach(function(Point p) {
pointCount += 1;
if lastPoint is Point {
distance += calculateDistance(<Point>lastPoint, p);
}
lastPoint = p;
});
decimal endTime = time:monotonicNow();
int elapsedTime = <int>(endTime - startTime);
return {point_count: pointCount, feature_count: featureCount, distance: distance, elapsed_time: elapsedTime};
}

// Bidirectional streaming RPC: receives and sends RouteNote streams
remote function RouteChat(RouteGuideRouteNoteCaller caller, stream<RouteNote, grpc:Error?> clientStream) returns error? {
check clientStream.forEach(function(RouteNote note) {
grpc:Error? err = caller->sendRouteNote(note);
});
}
}
note

For bidirectional and client streaming RPCs, the typed Caller (e.g., RouteGuideRouteNoteCaller) is auto-generated from the .proto file. It wraps the base grpc:Caller and provides typed send methods for the specific response message type.


Supporting types

ListenerSecureSocket

FieldTypeDescription
keycrypto:KeyStore|CertKeyThe server's certificate and private key configuration.
mutualSslMutualSslConfig?Mutual SSL configuration. Set verifyClient to REQUIRE or OPTIONAL.
protocolProtocolConfig?SSL/TLS protocol version configuration.
ciphersstring[]List of cipher suites to use for TLS.
handshakeTimeoutdecimal?SSL handshake timeout in seconds.
sessionTimeoutdecimal?SSL session timeout in seconds.

CertKey

FieldTypeDescription
certFilestringPath to the certificate file.
keyFilestringPath to the private key file.
keyPasswordstring?Password for the private key if it is encrypted.

RetryConfiguration

FieldTypeDescription
retryCountintMaximum number of retry attempts in a failure scenario.
intervaldecimalInitial interval (in seconds) between retry attempts.
maxIntervaldecimalMaximum interval (in seconds) between two retry attempts.
backoffFactordecimalMultiplier applied to the retry interval between attempts.
errorTypesErrorType[]Error types that trigger a retry. Defaults to [InternalError].

PoolConfiguration

FieldTypeDescription
maxActiveConnectionsintMax active connections per route (host:port). Default is -1 (unlimited).
maxIdleConnectionsintMaximum number of idle connections allowed per pool. Default is 1000.
waitTimedecimalMaximum time (in seconds) to wait for an idle connection. Default is 60.
maxActiveStreamsPerConnectionintMaximum active HTTP/2 streams per connection. Default is 50.