1
func (w *Worker) makeUnaryRequest(ctx *context.Context, reqMD *metadata.MD, input *dynamic.Message) error {
...
}

I need to modify the contents of input.

var data Response
payload_dataByte, _ := json.Marshal(input)
payload_dataRaw := json.RawMessage(string(payload_dataByte))  
_ = json.Unmarshal(payload_dataRaw, &data)
data.Updates[0].Entry.Metadata.Description = "18"

But I am having issues in converting it back to proto.Message or dynamic.Message.

new_input := &v1.SetRequest{}
data_byte, err := json.Marshal(data)
if err != nil {
    return err
}

data_raw_byte := json.RawMessage(data_byte)

if err := json.Unmarshal(data_raw_byte, new_input); err != nil {
    log.Fatalf("Unmarshal error: %v", err)
}

I get an error saying

2025/03/10 23:46:29 Unmarshal error: json: cannot unmarshal string into Go struct field Datapoint.updates.entry.value.timestamp of type timestamppb.Timestamp
exit status 1

2 Answers 2

1

You should use protojson to (Un)Marshal JSON to Protobufs.

The error suggests that field Datapoint.updates.entry.value.timestamp uses Google's Well-known types Timestamp and there's a Golang Module to handle this type timestamppb

foo.proto:

syntax = "proto3";

package protos;

import "google/protobuf/timestamp.proto";

option go_package = "github.com/DazWilkin/stackoverflow/79499375/protos";

message Foo {
  google.protobuf.Timestamp timestamp = 1;
}
Q="79499375"
MODULE="github.com/DazWilkin/stackoverflow/${Q}"

protoc \
--go_out=${PWD}/protos \
--go_opt=module=${MODULE}/protos \
foo.proto 

main.go:

package main

import (
    "time"

    "github.com/DazWilkin/stackoverflow/79499375/protos"

    "google.golang.org/protobuf/encoding/protojson"
    "google.golang.org/protobuf/types/known/timestamppb"
)

func main() {
    // Create a Foo
    foo := &protos.Foo{
        Timestamp: timestamppb.New(time.Date(2025, time.January, 1, 0, 0, 0, 0, time.Local)),
    }

    // Marshal Foo to JSON
    if b, err := protojson.Marshal(foo); err == nil {
        println(string(b))
    }

    // Update Foo
    foo.Timestamp = timestamppb.Now()

    // Marshal Foo to JSON
    if b, err := protojson.Marshal(foo); err == nil {
        println(string(b))
    }
}

Yields:

{"timestamp":"2025-01-01T08:00:00Z"}
{"timestamp":"2025-03-11T16:13:52.146526501Z"}
Sign up to request clarification or add additional context in comments.

Comments

0

If you are certain that your timestamp field is of type timestamppb.Timestamp (RFC 3339), using the (Un)Marshal functions from the encoding/json package should not result in any errors.

The root cause of your error is that the timestamp is of type string. You need to ensure that it is in the format "timestamp": {"seconds": 1741929864}.

You can use protojson.Unmarshal, but you also need to ensure that the timestamp field conforms to the RFC 3339 format. Otherwise, you will need to use Format(time.RFC3339) to convert it to the correct format.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.