如何通过 grpcurl 发送时间戳?
How to send a timestamp via grpcurl?
我正在使用 GRPC/proto-buffers 在 GoLang 中编写我的第一个 API 端点。我对 GoLang 很陌生。
下面是我正在为我的测试用例编写的文件
package my_package
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/structpb"
"github.com/MyTeam/myproject/cmd/eventstream/setup"
v1handler "github.com/MyTeam/myproject/internal/handlers/myproject/v1"
v1interface "github.com/MyTeam/myproject/proto/.gen/go/myteam/myproject/v1"
)
func TestEndpoint(t *testing.T) {
conf := &setup.Config{}
// Initialize our API handlers
myhandler := v1handler.New(&v1handler.Config{})
t.Run("Success", func(t *testing.T) {
res, err := myhandler.Endpoint(context.Background(), &v1interface.EndpointRequest{
A: "S",
B: &structpb.Struct{
Fields: map[string]*structpb.Value{
"T": &structpb.Value{
Kind: &structpb.Value_StringValue{
StringValue: "U",
},
},
"V": &structpb.Value{
Kind: &structpb.Value_StringValue{
StringValue: "W",
},
},
},
},
C: ×tamppb.Timestamp{Seconds: 1590179525, Nanos: 0},
})
require.Nil(t, err)
// Assert we got what we want.
require.Equal(t, "Ok", res.Text)
})
}
这是 EndpointRequest
对象在上面包含的 v1.go
文件中定义的方式:
// An v1 interface Endpoint Request object.
message EndpointRequest {
// a is something.
string a = 1 [(validate.rules).string.min_len = 1];
// b can be a complex object.
google.protobuf.Struct b = 2;
// c is a timestamp.
google.protobuf.Timestamp c = 3;
}
上面的测试用例似乎工作正常。
但是我想用 grpcurl 模拟这个相同的测试用例。
这个有效:
grpcurl -d '{"a": "S", "b": {"T": "U", "V": "W"}}' -plaintext localhost:11000 myteam.myproject.v1.MyProject/Endpoint
但是当我尝试以下操作时,它失败了:
grpcurl -d '{"a": "S", "b": {"T": "U", "V": "W"}, "c": "1590179525"}' -plaintext localhost:11000 myteam.myproject.v1.MyProject/Endpoint
Error invoking method "myteam.myproject.v1.MyProject/Endpoint": error getting request data: bad Timestamp: parsing time "1590179525" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "179525" as "-"
如何通过 grpcurl 发送时间戳?
google.protobuf.Timestamp is a timestamppb.Timestamp 的基础类型。
文档详细说明了 json 表示的格式:
JSON Mapping
In JSON format, the Timestamp type is encoded as a string in the RFC
3339 format. That is, the
format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
where {year} is always expressed using four digits while {month},
{day}, {hour}, {min}, and {sec} are zero-padded to two digits each.
The fractional seconds, which can go up to 9 digits (i.e. up to 1
nanosecond resolution), are optional. The "Z" suffix indicates the
timezone ("UTC"); the timezone is required. A proto3 JSON serializer
should always use UTC (as indicated by "Z") when printing the
Timestamp type and a proto3 JSON parser should be able to accept both
UTC and other timezones (as indicated by an offset).
For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
01:30 UTC on January 15, 2017.
这也可以在您收到的错误消息中看到:
parsing time "1590179525" as "2006-01-02T15:04:05.999999999Z07:00":
cannot parse "179525" as "-"
这是 Time.Parse 中描述的 Go 的标准时间解析。
因此,您不应传递自纪元以来的秒数字符串,而应传递字符串:
2020-05-22T20:32:05Z
以上字符串是通过运行获得的:
fmt.Println(time.Unix(1590179525, 0).Format(time.RFC3339))
我正在使用 GRPC/proto-buffers 在 GoLang 中编写我的第一个 API 端点。我对 GoLang 很陌生。 下面是我正在为我的测试用例编写的文件
package my_package
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/structpb"
"github.com/MyTeam/myproject/cmd/eventstream/setup"
v1handler "github.com/MyTeam/myproject/internal/handlers/myproject/v1"
v1interface "github.com/MyTeam/myproject/proto/.gen/go/myteam/myproject/v1"
)
func TestEndpoint(t *testing.T) {
conf := &setup.Config{}
// Initialize our API handlers
myhandler := v1handler.New(&v1handler.Config{})
t.Run("Success", func(t *testing.T) {
res, err := myhandler.Endpoint(context.Background(), &v1interface.EndpointRequest{
A: "S",
B: &structpb.Struct{
Fields: map[string]*structpb.Value{
"T": &structpb.Value{
Kind: &structpb.Value_StringValue{
StringValue: "U",
},
},
"V": &structpb.Value{
Kind: &structpb.Value_StringValue{
StringValue: "W",
},
},
},
},
C: ×tamppb.Timestamp{Seconds: 1590179525, Nanos: 0},
})
require.Nil(t, err)
// Assert we got what we want.
require.Equal(t, "Ok", res.Text)
})
}
这是 EndpointRequest
对象在上面包含的 v1.go
文件中定义的方式:
// An v1 interface Endpoint Request object.
message EndpointRequest {
// a is something.
string a = 1 [(validate.rules).string.min_len = 1];
// b can be a complex object.
google.protobuf.Struct b = 2;
// c is a timestamp.
google.protobuf.Timestamp c = 3;
}
上面的测试用例似乎工作正常。
但是我想用 grpcurl 模拟这个相同的测试用例。
这个有效:
grpcurl -d '{"a": "S", "b": {"T": "U", "V": "W"}}' -plaintext localhost:11000 myteam.myproject.v1.MyProject/Endpoint
但是当我尝试以下操作时,它失败了:
grpcurl -d '{"a": "S", "b": {"T": "U", "V": "W"}, "c": "1590179525"}' -plaintext localhost:11000 myteam.myproject.v1.MyProject/Endpoint
Error invoking method "myteam.myproject.v1.MyProject/Endpoint": error getting request data: bad Timestamp: parsing time "1590179525" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "179525" as "-"
如何通过 grpcurl 发送时间戳?
google.protobuf.Timestamp is a timestamppb.Timestamp 的基础类型。
文档详细说明了 json 表示的格式:
JSON Mapping
In JSON format, the Timestamp type is encoded as a string in the RFC 3339 format. That is, the format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone is required. A proto3 JSON serializer should always use UTC (as indicated by "Z") when printing the Timestamp type and a proto3 JSON parser should be able to accept both UTC and other timezones (as indicated by an offset).
For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on January 15, 2017.
这也可以在您收到的错误消息中看到:
parsing time "1590179525" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "179525" as "-"
这是 Time.Parse 中描述的 Go 的标准时间解析。
因此,您不应传递自纪元以来的秒数字符串,而应传递字符串:
2020-05-22T20:32:05Z
以上字符串是通过运行获得的:
fmt.Println(time.Unix(1590179525, 0).Format(time.RFC3339))