I'm developing a gRPC User Service in Go and facing issues with unmarshalling JSON that includes a google.protobuf.BoolValue
type field in the search criteria.
Here's my proto
file:
syntax = "proto3";
package user;
import "google/protobuf/wrappers.proto";
option go_package = "/pb;user";
message User {
int32 id = 1;
string fname = 2;
string city = 3;
int64 phone = 4;
float height = 5;
bool married = 6;
}
message UserID {
int32 id = 1;
}
message UserIDs {
repeated int32 ids = 1;
}
message SearchCriteria {
string city = 1;
int64 phone = 2;
google.protobuf.BoolValue married = 3;
}
message Users {
repeated User users = 1;
}
service UserService {
rpc GetUser(UserID) returns (User);
rpc GetUsers(UserIDs) returns (Users);
rpc SearchUsers(SearchCriteria) returns (Users);
}
Here’s the relevant part of my Go code for the server:
package main
import (
"context"
"database/sql"
"fmt"
"log"
"net"
pb "golang-grcp-user-services/pb"
_ "github.com/mattn/go-sqlite3"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/types/known/wrapperspb"
)
type server struct {
pb.UnimplementedUserServiceServer
db *sql.DB
}
func (s *server) SearchUsers(ctx context.Context, in *pb.SearchCriteria) (*pb.Users, error) {
var users []*pb.User
query := "SELECT id, fname, city, phone, height, married FROM users WHERE 1=1"
var args []interface{}
if in.City != "" {
query += " AND city LIKE ?"
args = append(args, "%"+in.City+"%")
}
if in.Phone != 0 {
phoneStr := fmt.Sprintf("%d", in.Phone)
query += " AND CAST(phone AS TEXT) LIKE ?"
args = append(args, "%"+phoneStr+"%")
}
if in.Married != nil {
query += " AND married = ?"
args = append(args, in.Married.Value)
}
rows, err := s.db.Query(query, args...)
if err != nil {
return nil, fmt.Errorf("failed to execute query: %v", err)
}
defer rows.Close()
for rows.Next() {
var user pb.User
err := rows.Scan(&user.Id, &user.Fname, &user.City, &user.Phone, &user.Height, &user.Married)
if err != nil {
return nil, fmt.Errorf("failed to scan row: %v", err)
}
users = append(users, &user)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating rows: %v", err)
}
return &pb.Users{Users: users}, nil
}
When I test with grpcurl
:
grpcurl -plaintext -d '{"phone": 9998887776, "married": {"value": false}}' localhost:50051 user.UserService/SearchUsers
I get the following error:
Error invoking method "user.UserService/SearchUsers": error getting request data: json: cannot unmarshal object into Go value of type bool
I have tried various approaches to resolve this issue, but none have worked so far. Any help or suggestions would be greatly appreciated!
gprcurl
, but did you trygrpcurl -plaintext -d '{"phone": 9998887776, "married": false}' localhost:50051 user.UserService/SearchUsers
instead? Have a look here: googleapis.github.io/gax-php/0.21.1/Google/Protobuf/…: "The JSON representation forBoolValue
is JSONtrue
andfalse
"