A unary RPC is equivalent to the request-response model that's used in traditional RESTful APIs. In the following example, we are defining a service with the name AccountService that exposes a CreateAccount method that receives CreateAccountRequest as input and returns a CreateAccountResponse to the caller:
message CreateAccountRequest {
string user_name = 1;
string password = 2;
string email = 3;
}
message CreateAccountResponse {
string account_id = 1;
}
service AccountService {
rpc CreateAccount (CreateAccountRequest) returns (CreateAccountResponse);
}
Defining the server handler is also quite similar to a regular RESTful API. Consider the following code:
var _ AccountServiceServer = (*server)(nil)
func (*server) CreateAccount(_ context.Context, req *CreateAccountRequest) (*CreateAccountResponse, error) {
accountID, err := createAccount(req)
if err != nil {
return nil, err
}
return &CreateAccountResponse{AccountId: accountID}, nil
}
To be able to register our server implementation with gRPC, we need to implement the AccountServiceServer interface. The server-side implementation in the listing (given in the preceding code snippet) receives a CreateAccountRequest message as an argument. It invokes the createAccount helper, which validates the request, creates the new account record, and returns its ID. Then, a new CreateAccountResponse instance is created and returned to the client.
On the client side, things are also quite simple. The following code shows that the accountAPI type simply offers a friendly API for abstracting the RPC call to the server:
func (a *accountAPI) CreateAccount(account model.Account) (string, error) {
req := makeCreateAccountRequest(account)
res, err := a.accountCli.CreateAccount(context.Background(), req)
if err != nil {
return "", err
}
return res.AccountId, nil
}
The method receives a model instance that describes the account to be created, converts it into CreateAccountInstance, and sends it to the server via the AccountServiceClient instance that was injected at construction time. Upon receiving a response, the client extracts the ID that was assigned to the new account and returns it to the caller.