凌云的博客

行胜于言

Proto 风格指南[译]

分类:proto| 发布时间:2025-01-15 08:40:00

原文:Style Guide

为如何最好的进行 proto 定义提供指导

本文档提供了一个 .proto 文件的样式指南。 遵循这些约定,可以使您的 protobuf buffer 消息定义及其对应的类保持一致且易于阅读。

请注意,protobuf buffer 样式随着时间的推移而不断演变,因此您可能会遇到不同约定或样式的 .proto 文件。 在修改现有文件时,请尊重其原有的样式一致性至关重要。 然而,在创建新的 .proto 文件时,建议采用当前最佳的样式。

标准文件格式

  • 保持每行最多 80 个字符
  • 使用两个空格进行缩进
  • 对字符串优先使用双引号

文件结构

文件应该命名为 lower_snaker_case.proto

每个的文件的内容块应该保持如下顺序:

  1. 许可证的头部(如果有)
  2. 文件概述
  3. 格式(syntax/editions)
  4. 包名(package)
  5. Imports(排序)
  6. 文件选项(options)
  7. 其他内容

包名(Packages)

包名应使用小写字母。 包名应基于项目名称,并可考虑基于包含的 protocol buffer 类型定义文件路径,以确保名称的唯一性。

消息和字段名称

使用 PascalCase (第一个字符大写)来命名消息类型,比如:SongServerRequest。 优先将缩写当成单个单词将其首字母变成大写:比如使用 GetDnsRequest 而不是 GetDNSRequest。 使用 lower_snake_case 作为字段名称,包括 oneof 字段和扩展名称:song_name

message SongServerRequest {
  optional string song_name = 1;
}

使用这种字段命名约定,您可以访问类似于以下两个代码示例中的访问器。

C++:

const string& song_name() { ... }
void set_song_name(const string& x) { ... }

Java:

public String getSongName() { ... }
public Builder setSongName(String v) { ... }

如果你的字段名称包含数字,数字应该紧跟在字母后面而不是跟在下划线后面。 比如,使用 song_name1 而不是 song_name_1

Repeated 自动

对 repeated 字段使用复数名称

repeated string keys = 1;
  ...
  repeated MyMessage accounts = 17;

枚举

使用 PascalCase (第一个字符大写)来命名枚举类型名称并且使用 CAPITALS_WITH_UNDERSCORES 作为值得名称:

enum FooBar {
  FOO_BAR_UNSPECIFIED = 0;
  FOO_BAR_FIRST_VALUE = 1;
  FOO_BAR_SECOND_VALUE = 2;
}

每个枚举值应该以分号结尾而不是逗号。

由于枚举值在语义上不受其所属枚举名称的影响,因此两个同级枚举中不允许使用相同的数值名称。 对于顶级枚举,名称冲突的风险尤其高,因为它们的同级枚举可能在其他具有相同包的文件中定义。 为了避免这些风险,强烈建议为每个枚举值添加枚举名称作为前缀,或者将枚举嵌套在包含的消息内部。

与将枚举嵌套在消息内部相比,更倾向于使用带有前缀值的顶级枚举。 由于某些语言不支持在“结构体”类型内部定义枚举,因此这种方式可以确保跨绑定语言的一致性。

零值枚举应该以 UNSPECIFIED 作为后缀,因为当服务器或应用程序收到一个意外的枚举值时,它会在 Proto 实例中将该字段标记为未设置。 然后,字段访问器将返回默认值,对于枚举字段,默认值为第一个枚举值。 有关未指定枚举值的更多信息,请参阅 Proto 最佳实践[译]

服务

如果你的 .proto 定义了一个 PRC 服务,你应该使用 PascalCase (第一个字符大写)来命名服务和任意 RPC 方法名:

service FooService {
  rpc GetSomething(GetSomethingRequest) returns (GetSomethingResponse);
  rpc ListSomething(ListSomethingRequest) returns (ListSomethingResponse);
}

可以通过 API 最佳实践的相关主题 Create Unique Protos per MethodDon’t Include Primitive Types in a Top-level Request or Response Proto 以及 Proto 最佳实践中的 Define Messages in Separate Files 查看更多服务相关的建议。

应该避免的事

  • required 字段(只有 proto2 有)
  • groups(只有 proto2 有)