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.