import ballerina/grpc;
import ballerina/log;service HelloWorld on new grpc:Listener(9090) {    resource function hello(grpc:Caller caller, string name,
                             grpc:Headers headers) {
        log:printInfo("Server received hello from " + name);
        string message = "Hello " + name;
        string reqHeader = headers.get("client_header_key") ?: "none";
        log:printInfo("Server received header value: " + reqHeader);
        grpc:Headers resHeader = new;
        resHeader.setEntry("server_header_key", "Response Header value");
        grpc:Error? err = caller->send(message, resHeader);
        if (err is grpc:Error) {
            log:printError("Error from Connector: " + err.message());
        }
        grpc:Error? result = caller->complete();
        if (result is grpc:Error) {
            log:printError("Error in sending completed notification to caller",
                err = result);
        }
    }
}
import ballerina/grpc;
import ballerina/io;public function main() {
    HelloWorldBlockingClient helloWorldBlockingEp =
                                             new ("http://localhost:9090");
    grpc:Headers headers = new;
    headers.setEntry("client_header_key", "Request Header Value");
    var unionResp = helloWorldBlockingEp->hello("WSO2", headers);
    if (unionResp is grpc:Error) {
        io:println("Error from Connector: " + unionResp.message());
    } else {
        string result;
        grpc:Headers resHeaders;
        [result, resHeaders] = unionResp;
        io:println("Client Got Response : " + result);
        string headerValue = resHeaders.get("server_header_key") ?: "none";
        io:println("Headers: " + headerValue);
    }
}

Unary Blocking

The gRPC Server Connector exposes the gRPC service over http2. This sample demonstrates how the gRPC unary service interacts with the gRPC blocking client, and how header values are handled.

For more information on the underlying module, see the GRPC module.

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

This is the service definition for the unary blocking/unblocking scenario.

# Create new Protocol Buffers definition file `grpc_unary_blocking.proto` and add service definition.
# Run the command below in Ballerina tools distribution for stub generation.
ballerina grpc --input grpc_unary_blocking.proto  --output stubs
# Once you run the command, `grpc_unary_blocking_pb.bal` file is generated inside stubs directory.
# Please refer example `Proto To Ballerina` to get information on how to use Ballerina Protocol Buffers tool.
import ballerina/grpc;
import ballerina/log;

This is the server implementation for the unary blocking/unblocking scenario.

service HelloWorld on new grpc:Listener(9090) {
    resource function hello(grpc:Caller caller, string name,
                             grpc:Headers headers) {
        log:printInfo("Server received hello from " + name);
        string message = "Hello " + name;
        string reqHeader = headers.get("client_header_key") ?: "none";
        log:printInfo("Server received header value: " + reqHeader);

Reads custom headers in request message.

        grpc:Headers resHeader = new;
        resHeader.setEntry("server_header_key", "Response Header value");

Writes custom headers to response message.

        grpc:Error? err = caller->send(message, resHeader);
        if (err is grpc:Error) {
            log:printError("Error from Connector: " + err.message());
        }

Sends response message with headers.

        grpc:Error? result = caller->complete();
        if (result is grpc:Error) {
            log:printError("Error in sending completed notification to caller",
                err = result);
        }
    }
}

Sends completed notification to caller.

# Create a Ballerina project and a module inside it.
# Copy generated stub file `grpc_unary_blocking_pb.bal` to the module.
# For example, if you create a module named `service`, copy the stub file to the `service` module.
# Add new Ballerina file `grpc_unary_blocking.bal` inside the `service` module and add service implementation.
# Execute the command below to build the 'service' module.
ballerina build service
# Run the service using the command below.
ballerina run target/bin/service.jar
import ballerina/grpc;
import ballerina/io;

This is client implementation for unary blocking scenario.

public function main() {
    HelloWorldBlockingClient helloWorldBlockingEp =
                                             new ("http://localhost:9090");

Client endpoint configuration.

    grpc:Headers headers = new;
    headers.setEntry("client_header_key", "Request Header Value");

Writes custom headers to request message.

    var unionResp = helloWorldBlockingEp->hello("WSO2", headers);

Executes unary blocking call with headers.

    if (unionResp is grpc:Error) {
        io:println("Error from Connector: " + unionResp.message());
    } else {
        string result;
        grpc:Headers resHeaders;
        [result, resHeaders] = unionResp;
        io:println("Client Got Response : " + result);
        string headerValue = resHeaders.get("server_header_key") ?: "none";
        io:println("Headers: " + headerValue);
    }
}

Reads message and headers from response.

# Create a Ballerina project and a module inside it.
# Copy generated stub file `grpc_unary_blocking_pb.bal` to the module.
# For example, if you create a module named `client`, copy the stub file to the `client` module.
# Add new Ballerina file `grpc_unary_blocking_client.bal` inside the `client` module and add client implementation.
# Execute the command below to build the 'client' module.
ballerina build client
# Run the client using the command below.
ballerina run target/bin/client.jar