Implementing gRPC Services

The topics below explain how to implement a gRPC service and write a client to invoke it.

Table of contents   Expand all   Collapse all

Execute the bal new service command to create a Ballerina package to implement the service. You view the output below.

Created new Ballerina package 'service' at service.

Execute the bal grpc --mode service --input admin.proto --output service/ command to create the gRPC service skeleton. You view the output below.

Successfully extracted library files.
Successfully generated ballerina file.

The AdminService_sample_service.bal file, which contains the service skeleton will be automatically generated in the default module directory of the service.

You can simply fill in the implementation of the service functions that are defined in it. For example, the following is the remote function generated for the add gRPC method.

remote function add(AddRequest value) returns AddResponse|error {
    // Implementation goes here.
}

The implementation of the add service function can be completed as follows.

remote function add(AddRequest value) returns AddResponse|error {
    int result = value.numbers.reduce(function(int n, int i) returns int => n + i, 0);
    return {result: result};
}

The below is the full implementation of the service.

import ballerina/grpc;
import ballerina/uuid;
 
listener grpc:Listener ep = new (9090);
 
map<Person> personMap = {};
 
@grpc:ServiceDescriptor {
   descriptor: ROOT_DESCRIPTOR,
   descMap: getDescriptorMap()
}
service "AdminService" on ep {
 
    remote function add(AddRequest value) returns AddResponse|error {
        int result = value.numbers.reduce(function(int n, int i) returns int => n + i, 0);
        return {result: result};
    }
    remote function multiply(MultiplyRequest value) returns MultiplyResponse|error {
        return {result: value.v1 * value.v2};
    }
    remote function addPerson(Person value) returns AddPersonResponse|error {
        value.id = uuid:createType1AsString();
        personMap[value.id] = value;
        return {id: value.id};
    }
    remote function getPerson(GetPersonRequest value) returns Person|error {
        Person? person = personMap[value.id];
        if person is Person {
            return person;
        } else {
            return error grpc:NotFoundError(string `Person value for id: ${value.id} doesn't exist.`);
        }
    }
}