在 gRPC Go 服务中解组 `google.protobuf.BoolValue` 时出错

问题描述 投票:0回答:1

我正在用 Go 开发 gRPC 用户服务,并面临着解组 JSON 的问题,其中在搜索条件中包含

google.protobuf.BoolValue
类型字段。

这是我的

proto
文件:

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);
}

这是我的服务器 Go 代码的相关部分:

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
}

当我用

grpcurl
测试时:

grpcurl -plaintext -d '{"phone": 9998887776, "married": {"value": false}}' localhost:50051 user.UserService/SearchUsers

我收到以下错误:

Error invoking method "user.UserService/SearchUsers": error getting request data: json: cannot unmarshal object into Go value of type bool

我尝试了各种方法来解决这个问题,但到目前为止还没有奏效。任何帮助或建议将不胜感激!

go microservices grpc go-grpc-middleware
1个回答
0
投票

@notx 是正确的。

向自己证明这一点的方法是执行相反的操作并从

SearchCriteria
生成 JSON:

package main

import (
    "log/slog"
    "os"

    pb "golang-grcp-user-services/pb"
    "google.golang.org/protobuf/encoding/protojson"
    "google.golang.org/protobuf/types/known/wrapperspb"
)
func main() {
    sc := &pb.SearchCriteria{
        Phone: 9998887776,
        Married: &wrapperspb.BoolValue{
            Value: false,
        },
    }
    b, err := protojson.Marshal(sc)
    if err != nil {
        slog.Error("unable to marshal", "err", err)
        os.Exit(1)
    }

    slog.Info("JSON", "b", string(b))
}

其产量:

{
  "phone":"9998887776",
  "married":false
}
© www.soinside.com 2019 - 2024. All rights reserved.