Module : grpc

Module overview

This module contains functions to support gRPC protocol based communication. gRPC is a framework developed by Google to support the RPC (Remote Procedure Call) protocol. The gRPC protocol is layered over HTTP/2. This protocol only supports client-initiated communication.

Protocol buffers

This is a mechanism to serialize the structured data introduced by Google and used by the gRPC framework. Specify the structured data that needs to be serialized in the .proto file. A sample .proto file is shown below.

syntax = "proto3";
import "google/protobuf/wrappers.proto";
service ServerStreaming {
     rpc receiveMessage(google.protobuf.StringValue) returns (stream google.protobuf.StringValue);
}

gRPC allows client applications to directly call the server-side methods using the auto-generated stubs. Protocol buffer compilers are used to generate the stubs for the specified language. In Ballerina, the stubs are generated using the built-in proto compiler.

Endpoints

Endpoints specify how the client and server communicate. This module supports service endpoints and client endpoints. The service endpoint specifies how the client communicates with the server. The client endpoint is automatically generated by passing the .proto file to a proto compiler.

The Ballerina tooling distribution provides a proto compiler to generate the Ballerina client endpoint. The client endpoint generated using the Ballerina proto compiler has two client endpoints. Use the endpoint to suit the use case.

RPC types

This module supports the following RPC client-to-service communication methods: unary, server streaming, client streaming, and bidirectional streaming. Listeners are used to support the asynchronous and streaming communication.

Unary

The server sends a response to each client request. Unary supports blocking and non-blocking communication.

Server streaming

The server sends multiple responses in an asynchronous manner for each client request.

Client streaming

The client sends multiple requests while the server sends a single response to these requests.

Bidirectional Streaming

The client and server send multiple requests and responses.

Ballerina code generator tool

Using below command to generate stub and sample code.

ballerina grpc --input [proto_file] --output [output_directory] --mode [service/client]

Options

--input - Set proto file path.

--output - Set output Ballerina source files directory.

--mode - Set mode (client or server) to generate code samples. If not specified, only the stub file is generated.

Unary communication

The sample given below contains a service that sends a response to each request using an auto-generated Ballerina stub.

// Server listener configuration.
listener grpc:Listener ep = new(9090);

// The gRPC service is attached to the server.
service SamplegRPCService on ep {
   // A resource that accepts a string message.
   resource function receiveMessage(grpc:Caller caller, string name) {
       // Print the received message.
       io:println("Received message from : " + name);
       // Send the response to the client.
       grpc:Error? err = caller->send("Hi " + name + "! Greetings from gRPC service!");

       // After sending the response, call ‘complete()’ to indicate that the response was 
       // completely sent.
       grpc:Error? result = caller->complete();
   }
}

The sample given below calls the above service in a blocking manner using an auto-generated Ballerina stub.

// Use ‘BlockingClient’ to execute the call in the blocking mode.
SamplegRPCServiceBlockingClient SamplegRPCServiceBlockingEp = new("http://localhost:9090");

// Create gRPC headers.
grpc:Headers headers = new;
headers.setEntry("id", "newrequest1");

// Call the method in the service using a client stub.
var responseFromServer = SamplegRPCServiceBlockingEp->receiveMessage("Ballerina", headers);
if (responseFromServer is [string, grpc:Headers]) {
    // If a response is received, print the payload.
    string result;
    grpc:Headers resHeaders;
    [result, resHeaders] = responseFromServer;
    io:println("Response received : " + result);
} else {
    // If an error is returned, print the error message.
    io:println("Error while connecting grpc end-point : " + responseFromServer.reason() + 
                                    " - " + <string>responseFromServer.detail()["message"]);
}

Server Streaming

The sample given below shows a server streaming service.

// Server listener configuration.
listener grpc:Listener ep = new(9090);

// The gRPC service is attached to the server.
service ServerStreaming on ep {
   // Set the Streaming Annotation to ‘true’. It specifies that the resource is capable of
   // sending multiple responses per request.
   @grpc:ResourceConfig { streaming: true }
   resource function receiveMessage(grpc:Caller caller, string name) {
       string[] greets = ["Hi", "Welcome"];
       io:println("HelloWorld");
       // Send multiple responses to the client.
       foreach string greet in greets {
           grpc:Error? err = caller->send(greet + " " + name + "! Greetings from Ballerina service");
           // If an error is returned, print the error message. print response message otherwise.
           if (err is grpc:Error) {
               io:println("Error from Connector: " + err.reason() + " - "
                                                   + <string>err.detail()["message"]);
           } else {
               io:println("send reply: " + msg);
           }
       }
       // Once the messages are sent to the server, call ‘complete()’ to indicate that the 
       // request was completely sent.
       grpc:Error? result = caller->complete();
   }
}

The sample given below calls the above service using the auto-generated Ballerina client stub and listens to the multiple responses from the server.

// Keep track of the message that were completely received.
boolean isCompleted = false;
public function main(string... args) {
   // Client endpoint configurations.
    ServerStreamingClient serverStreamingEp = new("http://localhost:9090");

    // Execute the service streaming call by registering a message listener.
    grpc:Error? result = serverStreamingEp->receiveMessage("test", ServerStreamingMessageListener);
    if (result is grpc:Error) {
        // If the service returns an error, print the error.
        io:println("Error occurred while sending event " + result.reason() + " - "
                                                        + <string>result.detail()["message"]);
    } else {
        io:println("Connected successfully to service");
    }
   // Waits for the service to send the message.
   while (!isCompleted) { }
}

// Define a listener service to receive the messages from the server.
service ServerStreamingMessageListener = service {

   // This resource method is invoked when the service receives a message.
   resource function onMessage(string message) {
       io:println("Response received from server: " + message);
   }
   
   // This resource method is invoked if an error is returned.
   resource function onError(error err) {
        io:println("Error from Connector: " + err.reason() + " - "
                                            + <string>err.detail()["message"]);
   }

   // Invoke this resource when the server sends all the responses to the request.
    resource function onComplete() {
       isCompleted = true;
       io:println("Server Complete Sending Responses.");
   }
}

Bidirectional Streaming

The sample given below includes a service that handles bidirectional streaming.

// Server listener configuration.
listener grpc:Listener ep = new(9090);

// Set the ‘clientStreaming’ and ‘serverStreaming’ to true. It specifies that the service 
// supports bidirectional streaming.
@grpc:ServiceConfig {
    name: "chat",
    clientStreaming: true,
    serverStreaming: true
}
service Chat on ep {

   // This resource method is invoked when there is a connection request from a client.
   resource function onOpen(grpc:Caller caller) {
       
   }

   // This resource method is invoked when the client sends a request.
   resource function onMessage(grpc:Caller caller, string message) {
   
   }
   
   // This resource method is invoked when the client returns an error while sending requests.
   resource function onError(grpc:Caller caller, error err) {
   
   }
   
   // This resource method is invoked when the client has finished sending requests.
   resource function onComplete(grpc:Caller caller) {
   
   }
}

The sample given below calls the above service.

// Client endpoint configuration.
ChatClient chatEp = new("http://localhost:9090");
    
grpc:StreamingClient ep;

// Call the relevant service.
var res = chatEp->chat(ChatMessageListener);
if (res is grpc:Error) {
    io:println("Error from Connector: " + res.reason() + " - "
                                        + <string>res.detail()["message"]);
    return;
} else {
    io:println("Initialized connection sucessfully.");
    ep = res;
}

// Send multiple messages to the service.
grpc:Error? connErr = ep->send("Hello");

// After sending the message, call ‘complete()’ to indicate that the request was completely sent. 
grpc:Error? result = ep->complete();

Records

ClientConfiguration Represents client endpoint configuration.
Detail Holds the details of an gRPC error
GrpcResourceConfig Service resource configuration. Sets only for server streaming service.
GrpcServiceConfig Service configuration. Sets only for client and bidirectional streaming service.
ListenerConfiguration Represents the gRPC server endpoint configuration.
ListenerOcspStapling OcspStapling record represents options related to check whether a certificate is revoked or not.
ListenerSecureSocket Configures the SSL/TLS options to be used for HTTP service.
Local Presents a read-only view of the local address.
PoolConfiguration Configurations for managing gRPC client connection pool.
Protocols Protocols record represents SSL/TLS protocol related options to be used for HTTP client/service invocation.
Remote Presents a read-only view of the remote address.
SecureSocket Provides configurations for facilitating secure communication with a remote HTTP endpoint.
ServiceDescriptorData Service descriptor data. This is for internal use.
ValidateCert ValidateCert record represents options related to check whether a certificate is revoked or not.

Objects

AbstractClientEndpoint

Represents abstract gRPC client endpoint. This abstract object is used in client endpoints generated by the Protocol Buffer tool.

Headers

Provides actions to read/write header values in gRPC request/response message.

Clients

Caller

Provides the gRPC remote functions for interacting with caller.

Client

The gRPC client endpoint provides the capability for initiating contact with a remote gRPC service. The API it provides includes functions to send request/error messages.

StreamingClient

Provides the gRPC streaming client actions for interacting with gRPC server.

Listeners

Listener

Represents server listener where one or more services can be registered. so that ballerina program can offer service through this listener.

Functions

prepareError

Prepare the error as gRPC specific Error.

Constants

OK

The gRPC error status code: 0 OK.

CANCELED

The gRPC error status code: 1 Canceled.

UNKNOWN

The gRPC error status code: 2 Unknown.

INVALID_ARGUMENT

The gRPC error status code: 3 Invalid Argument.

DEADLINE_EXCEEDED

The gRPC error status code: 4 Deadline Exceeded.

NOT_FOUND

The gRPC error status code: 5 Not Found.

ALREADY_EXISTS

The gRPC error status code: 6 Already Exists.

PERMISSION_DENIED

The gRPC error status code: 7 Permission Denied.

RESOURCE_EXHAUSTED

The gRPC error status code: 8 Resource Exhausted.

FAILED_PRECONDITION

The gRPC error status code: 9 Failed Precondition.

ABORTED

The gRPC error status code: 10 Aborted.

OUT_OF_RANGE

The gRPC error status code: 11 Out of Range.

UNIMPLEMENTED

The gRPC error status code: 12 Unimplemented.

INTERNAL

The gRPC error status code: 13 Internal.

UNAVAILABLE

The gRPC error status code: 14 Unavailable.

DATA_LOSS

The gRPC error status code: 15 Data Loss.

UNAUTHENTICATED

The gRPC error status code: 16 Unauthenticated.

COMPRESSION_AUTO

When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the outbound request/response accept-encoding/content-encoding option.

COMPRESSION_ALWAYS

Always set accept-encoding/content-encoding in outbound request/response.

COMPRESSION_NEVER

Never set accept-encoding/content-encoding header in outbound request/response.

CANCELLED_ERROR

Identifies cancelled error.

UNKNOWN_ERROR

Identifies unknown error.

INVALID_ARGUMENT_ERROR

Identifies invalid argument error.

DEADLINE_EXCEEDED_ERROR

Identifies deadline exceeded error.

NOT_FOUND_ERROR

Identifies not found error.

ALREADY_EXISTS_ERROR

Identifies already exists error.

PERMISSION_DENIED_ERROR

Identifies permission denied error.

UNAUTHENTICATED_ERROR

Identifies unauthenticated error

RESOURCE_EXHAUSTED_ERROR

Identifies resource exhausted error.

FAILED_PRECONDITION_ERROR

Identifies failed precondition error.

ABORTED_ERROR

Identifies aborted error.

OUT_OF_RANGE_ERROR

Identifies out of range error.

UNIMPLEMENTED_ERROR

Identifies unimplemented error.

INTERNAL_ERROR

Identifies internal error.

UNAVAILABLE_ERROR

Identifies unavailable error.

DATA_LOSS_ERROR

Identifies data loss error.

Annotations

ResourceConfig

Service resource configuration. Sets only for server streaming service.

ServiceConfig

Service configuration. Sets only for client and bidirectional streaming service.

ServiceDescriptor

Service descriptor data generated at compile time. This is for internal use.

Types

Compression

Options to compress using gzip or deflate.

AUTO: When service behaves as a HTTP gateway inbound request/response accept-encoding option is set as the outbound request/response accept-encoding/content-encoding option ALWAYS: Always set accept-encoding/content-encoding in outbound request/response NEVER: Never set accept-encoding/content-encoding header in outbound request/response

Error

Represents gRPC related errors.

ErrorType

Represents gRPC related error types.

Errors

AbortedError

Represents error occur when operation is aborted.

AleadyExistsError

Represents error occur when attempt to create an entity which already exists.

CancelledError

Represents the operation canceled(typically by the caller) error.

DataLossError

Represents unrecoverable data loss or corruption erros.

DeadlineExceededError

Represents operation expired before completion error.

FailedPreconditionError

Represents error occur when operation is rejected because the system is not in a state required for the operation's execution.

InternalError

Represents internal error.

InvalidArgumentError

Represents client specified an invalid argument error.

NotFoundError

Represents requested entity (e.g., file or directory) not found error.

OutOfRangeError

Represents error occur when specified value is out of range.

PermissionDeniedError

Represents error occur when the caller does not have permission to execute the specified operation.

ResourceExhaustedError

Represents error occur when the resource is exhausted.

UnKnownError

Represents unknown error.(e.g. Status value received is unknown)

UnauthenticatedError

Represents error occur when the request does not have valid authentication credentials for the operation.

UnavailableError

Represents error occur when the service is currently unavailable.

UnimplementedError

Represents error occur when operation is not implemented or not supported/enabled in this service.