GRPC не возвращает логическое значение, если значение ложно

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 05.02.2023 14:02

@tkausl получает это от моей основной службы отдыха, но на самом деле это не имеет значения, потому что я теряю это значение после цикла for в приведенном выше коде. log.Println("GetTodos: ", todosResp) возвращается GetTodos: [id:1 title:"aaa"]

Sevy 05.02.2023 14:11
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
2
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это по дизайну и для эффективности.

«Нулевым» значением для 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}))
  • или, если вы экспортируете JSON самостоятельно, вместо стандартной библиотеки (encoding/json) используйте маршалер JSON из этого пакета "google.golang.org/protobuf/encoding/protojson":
protojson.Marshaler{EmitDefaults: true}.Marshal(w, resp)

как указано в этом ответе.

Другие вопросы по теме