func (m *TodoServer) GetTodos(ctx context.Context, empty *emptypb.Empty) (*desc.GetTodosResponse, error) {
todos, err := m.todoService.GetTodos()
if err != nil {
return nil, err
}
todosResp := make([]*desc.GetTodosResponse_Todo, 0, len(todos))
for _, todo := range todos {
todosResp = append(todosResp, &desc.GetTodosResponse_Todo{
Id: todo.ID,
Title: todo.Title,
IsCompleted: todo.IsCompleted,
})
}
return &desc.GetTodosResponse{Todos: todosResp}, nil
}
service TodoService {
rpc GetTodos(google.protobuf.Empty) returns (GetTodosResponse) {}
}
message GetTodosResponse {
repeated Todo todos = 1;
message Todo {
int64 id = 1;
string title = 2;
bool is_completed = 3;
}
}
У меня есть одна запись в БД | идентификатор | название | is_completed | |-|-|-| | 1 | ааа | ложный |
приведенная выше функция возвращает {"todos": [{"id": "1", "title": "aaa"}]}
, но как только я изменю is_completed
на true
, результат будет правильным {"todos": [{"id": "1", "title": "aaa", "isCompleted": true}]}
@tkausl получает это от моей основной службы отдыха, но на самом деле это не имеет значения, потому что я теряю это значение после цикла for в приведенном выше коде. log.Println("GetTodos: ", todosResp)
возвращается GetTodos: [id:1 title:"aaa"]
Это по дизайну и для эффективности.
«Нулевым» значением для bool
является false
, поэтому при инициализации вашей структуры protobuf
значением false
поле не нужно указывать явно при использовании демаршалера encoding/json
стандартной библиотеки. В конце кодирования, если тег JSON поля включает квалификатор omitempty
, маршалер encoding/json
стандартной библиотеки удалит любые нулевые значения, что вы и видите.
Вы увидите такое же поведение со строковым полем Title
, если оно было ""
(то есть нулевое значение строки).
Глядя на ваш сгенерированный код (*.pb.go
), определение поля bool
структуры будет выглядеть примерно так:
type Todo struct {
// ...
IsCompleted bool `protobuf:"varint,5,opt,name=is_complete,proto3" json:"is_complete,omitempty"`
}
Таким образом, json:"...,omitempty"
инструктирует маршалер encoding/json
опускать любые нулевые значения во время маршалинга с такими тегами, как тезисы.
Если вы хотите переопределить это поведение:
omitempty
из сгенерированного кода (не рекомендуется, так как изменениями необходимо управлять в течение жизненного цикла разработки). Но если вам нужно, обратитесь к этому ответу;grpc-gateway
, переопределите это во время выполнения, например.gwmux := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{OrigName: true, EmitDefaults: true}))
encoding/json
) используйте маршалер JSON
из этого пакета "google.golang.org/protobuf/encoding/protojson"
:protojson.Marshaler{EmitDefaults: true}.Marshal(w, resp)
как указано в этом ответе.
Как распечатать этот результат?