protobuf
protobuf copied to clipboard
How correctly change the default value behavior by gogoprotobuf?
I have city.proto file where I described the pretty simple rpc method for creating a new record. If no values are passed to the fields, an empty string is written to the database. I want null to be written to the database in case of an empty value in the fields.
Other words, in the database I see the following:
| id | created_at | updated_at | deleted_at | name | country |
| 1 | 2020-05-19 22:48:28 | 2020-05-19 22:48:28 | NULL | | |
I'm trying to get the following result:
| id | created_at | updated_at | deleted_at | name | country |
| 1 | 2020-05-19 22:48:28 | 2020-05-19 22:48:28 | NULL | NULL | NULL |
From official documentation I know that for strings, the default value is the empty string. As you can see from my proto file I use well-known type google.protobuf.StringValue which I thought would change this default behavior.
Question: How correctly change the default value behavior by gogoprotobuf?
city.proty:
syntax = "proto3";
package proto;
import "google/api/annotations.proto";
import "google/protobuf/wrappers.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option go_package = "./proto";
service CityService {
rpc CreateCity(CreateCityRequest) returns (CreateCityResponse) {
option (google.api.http) = {
post: "/api/city"
body: "city"
};
}
}
message City {
google.protobuf.StringValue name = 1 [
json_name = "name",
(gogoproto.jsontag) = "name",
(gogoproto.wktpointer) = true,
(gogoproto.nullable) = true
];
google.protobuf.StringValue country = 2 [
json_name = "country",
(gogoproto.jsontag) = "country",
(gogoproto.wktpointer) = true,
(gogoproto.nullable) = true
];
}
message CreateCityRequest {
City city = 1 [
json_name = "city",
(gogoproto.jsontag) = "city"
];
}
message CreateCityResponse {}
I use a gorm package to communicate with the database.
models.go:
package models
import (
"my_app/proto"
"time"
)
type City struct {
Id uint64
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
proto.City
}
func (DealerGroup) TableName() string {
return "my_scheme.city"
}
controllers.go:
func (server *Server) CreateCity(context context.Context, request *proto.CreateCityRequest) (*proto.CreateCityResponse, error) {
city := models.City {
City: *request.City,
}
if err := databases.DBGORM.Create(&city).Error; err != nil {
return nil, status.Errorf(codes.Internal, err.Error())
}
return nil, nil
}
go version:
go version go1.12.9 windows/amd64
protoc version:
libprotoc 3.11.4
I used such protoc command to generate go code:
protoc -I. -I%GOPATH%/src --gogofaster_out=plugins=grpc:. proto/city.proto