Any

Any 包含任意序列化的消息以及描述序列化消息类型的URL。

JSON格式 Any值的JSON表示使用反序列化的嵌入式消息的常规表示,并带有一个@type包含URL类型的附加字段。例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package google.profile;
message Person {
  string first_name = 1;
  string last_name = 2;
}

{
  "@type": "type.googleapis.com/google.profile.Person",
  "firstName": <string>,
  "lastName": <string>
}

如果嵌入式消息类型是众所周知的并且具有自定义JSON表示形式,则将嵌入该表示形式,并添加一个字段value,该@type字段除包含该字段外还包含自定义JSON 。示例(针对message google.protobuf.Duration):

1
2
3
4
{
  "@type": "type.googleapis.com/google.protobuf.Duration",
  "value": "1.212s"
}

APi

Api是协议缓冲区服务的轻量级描述符。

BoolValue

bool的包装函式。

bool的JSON表示形式BoolValue是true和false。

BytesValue

bytes的包装函式。

BytesValue的JSON表示形式是JSON字符串。

DoubleValue

double的包装函式。

DoubleValue的JSON表示形式是JSON Number。

Duration

Duration表示带符号的固定长度的时间跨度,表示为纳秒分辨率下的秒数和秒的分数。它独立于任何日历和概念,例如“天”或“月”。它与Timestamp有关,因为两个Timestamp值之间的差是Duration,可以将其相加或相减。范围约为+ -10,000年。

示例1:使用伪代码从两个时间戳计算Duration。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Timestamp start = ...;
Timestamp end = ...;
Duration duration = ...;

duration.seconds = end.seconds - start.seconds;
duration.nanos = end.nanos - start.nanos;

if (duration.seconds < 0 && duration.nanos > 0) {
  duration.seconds += 1;
  duration.nanos -= 1000000000;
} else if (duration.seconds > 0 && duration.nanos < 0) {
  duration.seconds -= 1;
  duration.nanos += 1000000000;
}

示例2:使用伪代码从时间戳+Duration计算时间戳。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Timestamp start = ...;
Duration duration = ...;
Timestamp end = ...;

end.seconds = start.seconds + duration.seconds;
end.nanos = start.nanos + duration.nanos;

if (end.nanos < 0) {
  end.seconds -= 1;
  end.nanos += 1000000000;
} else if (end.nanos >= 1000000000) {
  end.seconds += 1;
  end.nanos -= 1000000000;
}

Empty

您可以重复使用的通用空消息,以避免在API中定义重复的空消息。一个典型的示例是将其用作API方法的请求或响应类型。例如:

1
2
3
service Foo {
  rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
}

Empty的JSON表示形式是空的JSON对象{}。

Emun

枚举类型定义。

EnumValue

枚举值定义。

Field

消息类型的单个字段。

Cardinality

字段是可选字段,必需字段还是重复字段。

Kind

基本字段类型。

FieldMask

FieldMask 代表一组符号字段路径,例如:

1
2
paths: "f.a"
paths: "f.b.d"

这里f表示在一些根消息的字段,a并且b在该消息中的字段中找到的f,并且d一个字段在消息中找到f.b。

字段掩码用于指定应由get操作(projection)返回或由update操作修改的字段子集。字段掩码还具有自定义JSON编码(请参见下文)。

Field Masks in Projections

当FieldMask指定投影时,API将过滤响应消息(或子消息)以仅包含在掩码中指定的那些字段。例如,考虑以下“预屏蔽”响应消息:

1
2
3
4
5
6
7
8
9
f {
  a : 22
  b {
    d : 1
    x : 2
  }
  y : 13
}
z: 8

在上一个示例中应用了掩码之后,API响应将不包含字段x,y或z的特定值(它们的值将设置为默认值,并在原始文本输出中省略):

1
2
3
4
5
6
f {
  a : 22
  b {
    d : 1
  }
}

除字段掩模的最后位置外,不允许重复字段。

如果get操作中不存在FieldMask对象,则该操作将应用于所有字段(就像已指定所有字段的FieldMask一样)。

请注意,字段掩码不一定适用于顶级响应消息。在进行REST获取操作的情况下,字段掩码直接应用于响应,但是在进行REST列表操作的情况下,掩码则应用于返回的资源列表中的每个消息。在REST自定义方法的情况下,可以使用其他定义。适用遮罩的位置将在API中明确记录及其声明。无论如何,对返回的一个或多个资源的影响是API必需的行为。

Field Masks in Update Operations

更新操作中的字段掩码指定要更新目标资源的哪些字段。要求API仅更改掩码中指定的字段的值,而其他字段保持不变。如果传入资源来描述更新的值,则API将忽略掩码未涵盖的所有字段的值。

为了将字段的值重置为默认值,该字段必须位于掩码中,并在提供的资源中设置为默认值。因此,为了重置资源的所有字段,请提供资源的默认实例并在掩码中设置所有字段,或者不提供掩码,如下所述。

如果更新时不存在字段掩码,则该操作将应用于所有字段(就像已指定所有字段的字段掩码一样)。请注意,在存在模式演化的情况下,这可能意味着客户端不知道并因此未填写到请求中的字段将重置为默认值。如果这是不希望的行为,则特定服务可能要求客户端始终指定字段掩码,否则将产生错误。

与get操作一样,描述请求消息中更新值的资源位置取决于操作种类。在任何情况下,API都必须遵守字段掩码的作用。

HTTP REST的注意事项

为了满足HTTP语义,必须将使用字段掩码的HTTP类型的更新操作设置为PATCH而不是PUT(PUT必须仅用于完全更新)。

字段掩码的JSON编码

在JSON中,字段掩码编码为单个字符串,其中路径之间用逗号分隔。每个路径中的字段名称都与下层骆驼命名约定相互转换。

例如,请考虑以下消息声明:

1
2
3
4
5
6
7
8
message Profile {
  User user = 1;
  Photo photo = 2;
}
message User {
  string display_name = 1;
  string address = 2;
}

在原始的掩码中,Profile可能看起来像这样:

1
2
3
4
mask {
  paths: "user.display_name"
  paths: "photo"
}

在JSON中,相同的掩码表示如下:

1
2
3
{
  mask: "user.displayName,photo"
}

FloatValue

float的包装函式。

FloatValue的JSON表示形式是JSON Number。

Int32Value

int32的包装函式。

Int32Value的JSON表示形式是JSON Number。

Int64Value

int64的包装函式。

Int64Value的JSON表示形式是JSON字符串。

ListValue

ListValue 是围绕值的重复字段的包装。

ListValue的JSON表示形式是JSON数组。

Method

方法表示api的方法。

Mixin

声明要包含在此API中的API。包含的API必须从包含的API中重新声明所有方法,但是文档和选项的继承方式如下:

  • 如果在注释和空格剥离之后,重新声明的方法的文档字符串为空,则它将从原始方法继承。

  • 属于服务配置(http,可见性)的未在重新声明的方法中设置的每个注释都将被继承。

  • 如果继承了http批注,则将按以下方式修改路径模式。root如果指定的话,任何版本前缀都将被包含API的版本以及路径所代替。

一个简单的mixin示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package google.acl.v1;
service AccessControl {
  // Get the underlying ACL object.
  rpc GetAcl(GetAclRequest) returns (Acl) {
    option (google.api.http).get = "/v1/{resource=**}:getAcl";
  }
}

package google.storage.v2;
service Storage {
  //       rpc GetAcl(GetAclRequest) returns (Acl);

  // Get a data record.
  rpc GetData(GetDataRequest) returns (Data) {
    option (google.api.http).get = "/v2/{resource=**}";
  }
}

mixin配置示例:

1
2
3
4
apis:
- name: google.storage.v2.Storage
  mixins:
  - name: google.acl.v1.AccessControl

mixin构造意味着AccessControl中的所有方法也都声明了相同的名称和请求/响应类型Storage。文档生成器或注释处理器Storage.GetAcl在继承文档和注释之后将看到有效的方法,如下所示:

1
2
3
4
5
6
7
service Storage {
  // Get the underlying ACL object.
  rpc GetAcl(GetAclRequest) returns (Acl) {
    option (google.api.http).get = "/v2/{resource=**}:getAcl";
  }
  ...
}

请注意,路径模式中的版本如何从更改v1为v2。

如果root指定了mixin中的字段,则它应该是放置继承的HTTP路径的相对路径。例子:

1
2
3
4
5
apis:
* name: google.storage.v2.Storage
  mixins:
  * name: google.acl.v1.AccessControl
    root: acls

这意味着以下继承的HTTP批注:

1
2
3
4
5
6
7
service Storage {
  // Get the underlying ACL object.
  rpc GetAcl(GetAclRequest) returns (Acl) {
    option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
  }
  ...
}

NullValue

NullValue是一个单例枚举,表示Value类型联合的空值。

的JSON表示形式NullValue是JSON null。

Option

协议缓冲区选项,可以附加到消息,字段,枚举等。

SourceContext

SourceContext 表示有关protobuf元素来源的信息,例如定义它的文件。

StringValue

string的包装函式。

StringValue的JSON表示形式是JSON字符串。

Struct

Struct表示结构化的数据值,由映射到动态类型值的字段组成。在某些语言中,Struct本机表示可能会支持它。例如,在像JS这样的脚本语言中,结构表示为一个对象。该表示的详细信息与该语言的原始支持一起进行了描述。

Struct的JSON表示形式是JSON对象。

Syntax

定义协议缓冲区元素的语法。

Timestamp

时间戳表示与任何时区或日历无关的时间点,以UTC纪元时间中的纳秒分辨率表示为秒和几分之一秒。它使用Proleptic Gregorian日历进行编码,该日历将Gregorian日历向后扩展到第一年。假设所有分钟都是60秒长,即leap抹了“leap秒”,那么就进行编码,因此不需要leap秒表进行解释。范围是0001-01-01T00:00:00Z至9999-12-31T23:59:59.999999999Z。通过限制该范围,我们确保可以在RFC 3339日期字符串之间来回转换。参见https://www.ietf.org/rfc/rfc3339.txt

示例1:从POSIX计算时间戳time()。

1
2
3
Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);

示例2:从POSIX计算时间戳gettimeofday()。

1
2
3
4
5
6
struct timeval tv;
gettimeofday(&tv, NULL);

Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);

示例3:从Win32计算时间戳GetSystemTimeAsFileTime()。

1
2
3
4
5
6
7
8
9
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;

// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
Timestamp timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));

示例4:从Java计算时间戳System.currentTimeMillis()。

1
2
3
4
long millis = System.currentTimeMillis();

Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
    .setNanos((int) ((millis % 1000) * 1000000)).build();

示例5:从Python中的当前时间计算时间戳。

1
2
3
4
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
timestamp = Timestamp(seconds=seconds, nanos=nanos)

Type

协议缓冲区消息类型。

UInt32Value

uint32的包装函式。

UInt32Value的JSON表示形式是JSON Number。

UInt64Value

uint64的包装函式。

UInt64Value的JSON表示形式是JSON字符串。

Value

Value表示一个动态类型的值,该值可以为null,数字,字符串,布尔值,递归结构值或值列表。Value生产者应设置其中一个变量,如果不存在任何变量,则表明存在错误。

Value的JSON表示形式是JSON值。