others-how to grpcurl error invoking method error?

1. Purpose

In this post, I will show you how to solve the following error when using grpcurl tool to access a grpc service:

➜  score-segment git:(master) ✗ grpcurl -plaintext  -d '{"city_code":10}' localhost:8000 com.bswen.microservices.cityscore.service/calculateCityScore
Error invoking method "com.bswen.microservices.cityscore.service/calculateCityScore": target server does not expose service "com.bswen.microservices.cityscore.service"
➜  score-segment git:(master) ✗ grpcurl -plaintext  -d '{"city_code":10}' localhost:8000 com.bswen.microservices.cityscore/calculateCityScore 
Error invoking method "com.bswen.microservices.cityscore/calculateCityScore": target server does not expose service "com.bswen.microservices.cityscore"
➜  score-segment git:(master) ✗ grpcurl -plaintext  -d '{"city_code":10}' localhost:8000 cityscore/calculateCityScore
Error invoking method "cityscore/calculateCityScore": target server does not expose service "cityscore"

Here is the protobuf interface file content:

syntax = "proto3";  
  
import "google/protobuf/timestamp.proto";  
  
package cityscore;  
  
option java_package = "com.bswen.gprc.cityscore";  
option java_multiple_files = true;  
  
message CityScoreRequest {  
  int32 city_code = 1;  
}  
  
message CityScoreResponse {  
  int32 city_score = 1;  
}  
  
enum CityScoreErrorCode {  
  INVALID_CITY_CODE_VALUE = 0;  
  CITY_CODE_CANNOT_BE_NULL = 1;  
}  
  
message CityScoreExceptionResponse {  
  google.protobuf.Timestamp timestamp = 1;  
  CityScoreErrorCode error_code = 2;  
}  
  
service CityScoreService {  
  // unary  
  rpc calculateCityScore(CityScoreRequest) returns (CityScoreResponse) {};  
}

You can see that I have defined a grpc service named CityScoreService which accepts a CityScoreRequest and return a CityScoreResponse. The response will contain the score of the city.

Now I want to test the grpc service CityScoreService’s calculateCityScore method using grpcurl.

2. Solution

2.1 What is grpcurl?

If you are familiar with curl, you will want a similar tool to test grpc services, here comes the grpcurl. What is it?

Like cURL, but for gRPC: Command-line tool for interacting with gRPC servers

grpcurl is a command-line tool that lets you interact with gRPC servers. It’s basically curl for gRPC servers.

The main purpose for this tool is to invoke RPC methods on a gRPC server from the command-line.

grpcurl supports all kinds of RPC methods, including streaming methods. You can even operate bi-directional streaming methods interactively by running grpcurl from an interactive terminal and using stdin as the request body!

You can install grpcurl as follows on macos:

brew install grpcurl

You can also install grpcurl on a variety of environments, including Windows and myriad Linux distributions.You can see more details and the full list of other packages for grpcurl at repology.orghttps://repology.org/project/grpcurl/information

Example of using grpcurl to test your grpc service:

grpcurl grpc.server.com:443 my.custom.server.Service/Method

# no TLS
grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method

The first command test a grpc service running over a TLS connection, and the second just use plaintext (no TLS) option to connect a normal grpc service.

2.2 The solution to the error

We got the error because we have called the wrong name of the method, first, we should try to list all the grpc service as follows:

grpcurl -plaintext localhost:8000 list

Then you will get this:

cityscore.CityScoreService
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

The first line is our target, then we can call it as follows:

➜  grpc git:(master) ✗ grpcurl -plaintext  -d '{"city_code":10}' localhost:8000 cityscore.CityScoreService/calculateCityScore
{
  "city_score": 100
}

The schema is package/serviceName/methodName, you can see that we got the response.

It works!

3. Summary

In this post, I demonstrated how to solve the target server does not expose service error when trying to invoke a grpc method in command line using grpcurl, the key point is to get the right name of the service . That’s it, thanks for your reading.