为了能够长时间在众多 API 中为开发者提供一致的体验,API 使用的所有名称都应该具有以下特点:
- 简单
- 直观
- 一致
这包括接口、资源、集合、方法和消息的名称。
由于很多开发者不是以英语为母语,所以这些命名惯例的目标之一是确保大多数开发者可以轻松理解 API。对于方法和资源,我们鼓励使用简单、一致和少量的词汇来命名。
- API 中使用的名称应采用正确的美式英语。例如,使用美式英语的 license、color,而非英式英语的 licence、colour。
- 为了简化命名,可以使用已被广泛接受的简写形式或缩写。例如,API 优于 Application Programming Interface。
- 尽量使用直观、熟悉的术语。例如,如果描述移除(和销毁)一个资源,则删除优于擦除。
- 使用相同的名称或术语命名同样的概念,包括跨 API 共享的概念。
- 避免名称过载。使用不同的名称命名不同的概念。
- 避免在 API 的上下文以及范围更大的 Google API 生态系统中使用含糊不清、过于笼统的名称。这些名称可能导致对 API 概念的误解。相反,应选择能准确描述 API 概念的名称。这对定义一阶 API 元素(例如资源)的名称尤其重要。没有需避免名称的明确列表,因为每个名称都必须放在其他名称的上下文中进行评估。实例、信息和服务的名称都曾出现过这类问题。所选择的名称应清楚地描述 API 概念(例如:什么的实例?),并将其与其他相关概念区分开(例如:“alert”是指规则、信号还是通知?)。
- 仔细考虑使用的名称是否可能与常用编程语言中的关键字存在冲突。您可以使用这些名称,但在 API 审核期间可能会触发额外的审查。因此应明智而审慎地使用。
产品名称
产品名称是指 API 的产品营销名称,例如 Google Calendar API。API、界面、文档、服务条款、对账单和商业合同等信息中使用的产品名称必须一致。Google API 必须使用产品团队和营销团队批准的产品名称。
下表显示了所有相关 API 名称及其一致性的示例。如需详细了解各自名称及其命名惯例,请参阅本页面下方的详细信息。
API 名称 | 示例 |
---|---|
产品名称 | Google Calendar API |
服务名称 | calendar.googleapis.com |
软件包名称 | google.calendar.v3 |
接口名称 | google.calendar.v3.CalendarService |
来源目录 | //google/calendar/v3 |
API 名称 | calendar |
服务名称
服务名称应该是语法上有效的 DNS 名称(遵循 RFC 1035),可以解析为一个或多个网络地址。公开的 Google API 的服务名称采用 xxx.googleapis.com
格式。例如,Google 日历的服务名称是 calendar.googleapis.com
。
如果一个 API 是由多项服务组成,则应采用更容易发现的命名方式。要做到这点,一种方法是使服务名称共享一个通用前缀。例如,build.googleapis.com
和 buildresults.googleapis.com
服务都属于 Google Build API。
软件包名称
API .proto 文件中声明的软件包名称应该与产品名称和服务名称保持一致。软件包名称应该使用单数组件名称,以避免混合使用单数和复数组件名称。软件包名称不能使用下划线。进行版本控制的 API 的软件包名称必须以此版本结尾。例如:
// Google Calendar API
package google.calendar.v3;
与服务无直接关联的抽象 API(例如 Google Watcher API)应该使用与产品名称一致的 proto 软件包名称:
// Google Watcher API
package google.watcher.v1;
API .proto 文件中指定的 Java 软件包名称必须与带有标准 Java 软件包名称前缀(com.
、edu.
、net.
等)的 proto 软件包名称相匹配。例如:
package google.calendar.v3;
// Specifies Java package name, using the standard prefix "com."
option java_package = "com.google.calendar.v3";
集合 ID
集合 ID 应采用复数和 lowerCamelCase
(小驼峰式命名法)格式,并遵循美式英语拼写和语义。例如:events
、children
或 deletedEvents
。
接口名称
为了避免与服务名称(例如 pubsub.googleapis.com
)混淆,术语 “接口名称”是指在 .proto 文件中定义 service
时使用的名称:
// Library is the interface name.
service Library {
rpc ListBooks(...) returns (...);
rpc ...
}
您可以将服务名称视为对一组 API 实际实现的引用,而接口名称则是 API 的抽象定义。
接口名称应该使用直观的名词,例如 Calendar 或 Blob。该名称不得与编程语言及其运行时库(如 File)中的成熟概念相冲突。
在极少数情况下,接口名称会与 API 中的其他名称相冲突,此时应该使用后缀(例如 Api
或 Service
)来消除歧义。
方法名称
服务可以在其 IDL 规范中定义一个或多个远程过程调用 (RPC) 方法,这些方法需与集合和资源上的方法对应。方法名称应采用大驼峰式命名格式并遵循 VerbNoun
的命名惯例,其中 Noun(名词)通常是资源类型。
动词 | 名词 | 方法名称 | 请求消息 | 响应消息 |
---|---|---|---|---|
List |
Book |
ListBooks |
ListBooksRequest |
ListBooksResponse |
Get |
Book |
GetBook |
GetBookRequest |
Book |
Create |
Book |
CreateBook |
CreateBookRequest |
Book |
Update |
Book |
UpdateBook |
UpdateBookRequest |
Book |
Rename |
Book |
RenameBook |
RenameBookRequest |
RenameBookResponse |
Delete |
Book |
DeleteBook |
DeleteBookRequest |
google.protobuf.Empty |
方法名称的动词部分应该使用用于要求或命令的祈使语气,而不是用于提问的陈述语气。
对于标准方法,方法名称的名词部分对于除 List
之外的所有方法必须采用单数形式,而对于 List
必须采用复数形式。对于自定义方法,名词在适当情况下可以采用单数或复数形式。批处理方法必须采用复数名词形式。
如果关于 API 子资源的方法名称使用提问动词(经常使用陈述语气表示),则容易让人混淆。例如,要求 API 创建一本书,这显然是 CreateBook
(祈使语气),但是询问 API 关于图书发行商的状态可能会使用陈述语气,例如 IsBookPublisherApproved
或 NeedsPublisherApproval
。若要在此类情况下继续使用祈使语气,请使用“check”(CheckBookPublisherApproved
) 和“validate”(ValidateBookPublisher
) 等命令。
方法名称不应包含介词(例如“For”、“With”、“At”、“To”)。通常,带有介词的方法名称表示正在使用新方法,应将一个字段添加到现有方法中,或者该方法应使用不同的动词。
例如,如果 CreateBook
消息已存在且您正在考虑添加 CreateBookFromDictation
,请考虑使用 TranscribeBook
方法。
消息名称
消息名称应该简洁明了。避免不必要或多余的字词。如果不存在无形容词的相应消息,则通常可以省略形容词。例如,如果没有非共享代理设置,则 SharedProxySettings
中的 Shared
是多余的。
消息名称不应包含介词(例如“With”、“For”)。通常,带有介词的消息名称可以通过消息上的可选字段来更好地表示。
请求和响应消息
RPC 方法的请求和响应消息应该分别以带有后缀 Request
和 Response
的方法名称命名,除非方法请求或响应类型为以下类型:
- 一条空消息(使用
google.protobuf.Empty
)、 - 一个资源类型,或
- 一个表示操作的资源
这通常适用于在标准方法 Get
、Create
、Update
或 Delete
中使用的请求或响应。
枚举名称
枚举类型必须使用 UpperCamelCase 格式的名称。
枚举值必须使用 CAPITALIZED_NAMES_WITH_UNDERSCORES 格式。每个枚举值必须以分号(而不是逗号)结尾。第一个值应该命名为 ENUM_TYPE_UNSPECIFIED,因为在枚举值未明确指定时系统会返回此值。
enum FooBar {
// The first value represents the default and must be == 0.
FOO_BAR_UNSPECIFIED = 0;
FIRST_VALUE = 1;
SECOND_VALUE = 2;
}
封装容器
封装 proto2 枚举类型(其中 0
值具有非 UNSPECIFIED
的含义)的消息应该以后缀 Value
来命名,并具有名为 value
的单个字段。
enum OldEnum {
VALID = 0;
OTHER_VALID = 1;
}
message OldEnumValue {
OldEnum value = 1;
}
字段名称
.proto 文件中的字段定义必须使用 lower_case_underscore_separated_names 格式。这些名称将映射到每种编程语言的生成代码中的原生命名惯例。
字段名称不应包含介词(例如“for”、“during”、“at”),例如:
reason_for_error
应该改成error_reason
cpu_usage_at_time_of_failure
应该改成failure_time_cpu_usage
字段名称不应使用后置形容词(名词后面的修饰符),例如:
items_collected
应该改成collected_items
objects_imported
应该改成imported_objects
重复字段名称
API 中的重复字段必须使用正确的复数形式。这符合现有 Google API 的命名惯例和外部开发者的共同预期。
时间和时间段
要表示一个与任何时区或日历无关的时间点,应该使用 google.protobuf.Timestamp
,并且字段名称应该以 time
(例如 start_time
和 end_time
)结尾。
如果时间指向一个活动,则字段名称应该采用 verb_time
的形式,例如 create_time
和 update_time
。请勿使用动词的过去时态,例如 created_time
或 last_updated_time
。
要表示与任何日历和概念(如“天”或“月”)无关的两个时间点之间的时间跨度,应该使用 google.protobuf.Duration
。
message FlightRecord {
google.protobuf.Timestamp takeoff_time = 1;
google.protobuf.Duration flight_duration = 2;
}
如果由于历史性或兼容性原因(包括系统时间、时长、推迟和延迟),您必须使用整数类型表示与时间相关的字段,那么字段名称必须采用以下格式:
xxx_{time|duration|delay|latency}_{seconds|millis|micros|nanos}
message Email {
int64 send_time_millis = 1;
int64 receive_time_millis = 2;
}
如果由于历史性或兼容性原因,您必须使用字符串类型表示时间戳,则字段名称不应该包含任何单位后缀。字符串表示形式应该使用 RFC 3339 格式,例如“2014-07-30T10:43:17Z”。
日期和时间
对于与时区和时段无关的日期,应该使用 google.type.Date
,并且该名称应具有后缀 _date
。如果日期必须表示为字符串,则应采用 ISO 8601 日期格式 YYYY-MM-DD,例如 2014-07-30。
对于与时区和日期无关的时间,应该使用 google.type.TimeOfDay
,并且该名称应具有后缀 _time
。如果时间必须表示为字符串,则应采用 ISO 8601 24 小时制格式 HH:MM:SS[.FFF],例如 14:55:01.672。
message StoreOpening {
google.type.Date opening_date = 1;
google.type.TimeOfDay opening_time = 2;
}
数量
由整数类型表示的数量必须包含度量单位。
xxx_{bytes|width_pixels|meters}
如果数量是条目计数,则该字段应该具有后缀 _count
,例如 node_count
。
列表过滤器字段
如果 API 支持对 List
方法返回的资源进行过滤,则包含过滤器表达式的字段应该命名为 filter
。例如:
message ListBooksRequest {
// The parent resource name.
string parent = 1;
// The filter expression.
string filter = 2;
}
列表响应
List
方法的响应消息(包含资源列表)中的字段名称必须是资源名称本身的复数形式。例如,CalendarApi.ListEvents()
方法必须为返回的资源列表定义一个响应消息ListEventsResponse
,其中包含一个名为 events
的重复字段。
service CalendarApi {
rpc ListEvents(ListEventsRequest) returns (ListEventsResponse) {
option (google.api.http) = {
get: "/v3/{parent=calendars/*}/events";
};
}
}
message ListEventsRequest {
string parent = 1;
int32 page_size = 2;
string page_token = 3;
}
message ListEventsResponse {
repeated Event events = 1;
string next_page_token = 2;
}
驼峰式命名法
除字段名称和枚举值外,.proto
文件中的所有定义都必须使用由 Google Java 样式定义的 UpperCamelCase 格式的名称。
名称缩写
对于软件开发者熟知的名称缩写,例如 config
和 spec
,应该在 API 定义中使用这些缩写,而非完整名称。这将使源代码易于读写。而在正式文档中,应该使用完整名称。示例:
- config (configuration)
- id (identifier)
- spec (specification)
- stats (statistics)