• 资源命名
    • 资源全名
    • 相对资源名称
    • 资源ID
    • 资源组ID
    • 资源名称 vs URL
    • 作为字符串的资源名称

    资源命名

    在面向资源的API中,资源是命名实体,资源名称是资源的标识符。每个资源必须有其唯一的资源名称。资源名称由资源ID本身,父资源的ID和资源对应的API服务名称组成。在下文,我们将探讨资源ID和如何构建资源名称。

    gRPC API应该使用无模式的URIs作为资源名称。它们通常遵循REST URL的惯例并且表现得更像网络文件路径。它们可以轻松的映射到REST URL上:细节请参考下一节标准方法。

    资源组是一种特殊的资源,它包含一组相同类型的子资源。例如,一个目录是一组文件资源。组的资源ID被称为组ID。

    资源名称使用组ID和资源ID分层组织,以斜杠(译者注:/,下同)分割。如果某个资源包含子资源,子资源的名称为:父资源名称,斜杠,子资源ID。

    例1:一个存储服务有一组bucket,每一个bucket有一组objects

    API资源名称 组ID 资源ID 组ID 资源ID
    //storage.googleapis.com /buckets bucket-id objects object-id

    例2:一个邮件服务有一组user,每个user有子资源settings,settings还有子资源customFrom

    API资源名称 组ID 资源ID 组ID 资源ID
    //mail.googleapis.com /users name@example.com settings customFrom

    API的提供者可以选择任何可接受的值作为资源和资源组的ID,只要它们在资源的层次结构中是唯一的即可。关于选择合适的资源ID和资源组ID,下文还有更多的参考。

    只要资源名称的每段都不包含斜杠,通过分割资源名称可以获取独立的资源组ID和资源ID,比如name.split("/")[n]

    资源全名

    规则松散的URI由DNS兼容的API服务名称和资源路径组成。资源路径也称为相对资源名称。

    “//library.googleapis.com/shelves/shelf1/books/book2”

    API服务名称用于定位API服务端;它也可以是仅供内部的服务的伪DNS名称(译者注:API服务名可能用于外部调用,也可能只用于内部调用)。如果API服务名称在上下文中比较明显,相对资源名称则比较常用。

    相对资源名称

    没有前导“/”的URI路径(路径-无模式),标识API服务中的一个资源。比如:

    “shelves/shelf1/books/book2”

    资源ID

    一个非空的URI片段(segment-nz-nc)标识父资源中的资源。比如上例。

    资源名称中的资源ID后缀可以有不止一个URI片段。比如:

    资源组ID 资源ID
    files /source/py/parser.py

    API服务应当尽可能的使用URL友好的资源ID。资源ID必须清楚的描述,不管它是由客户端、服务器端还是其他方指定。

    资源组ID

    一个非空的URI片段(segment-nz-nc)标识父资源中的资源组,比如上例。

    因为资源组ID经常出现在生成的客户端库里,它们必须符合以下要求:

    • 必须是有效的C/C++标识符。
    • 必须是驼峰命名的复数形式;首字母小写。
    • 必须使用清晰简明的英文词语。
    • 应当避免或者限定过于笼统的词语。比如,RowValue优于Value。没有限定的情况下应当避免以下词语:
      • Element
      • Entry
      • Instance
      • Item
      • Object
      • Resource
      • Type
      • Value

    资源名称 vs URL

    虽然完整的资源名称类似于普通URL,但他们不是一回事。单个资源可以由不同版本的API和不同API的协议暴露出来。完整资源名称没有指定API的协议和版本,在实际使用中,它必须被映射到特定的协议和API版本(译者注:完整资源名称)。

    为了通过REST API使用资源的全名,必须在服务名称前添加HTTP协议,在资源路径前添加API主要版本号以及对资源路径进行URL转义,将其转换为REST URL。比如:

    //这是一个日历事件资源名称

    “//calendar.googleapis.com/users/john smith/events/123”

    这是对应的HTTP URL

    “https://calendar.googleapis.com/v3/users/john%20smith/events/123“

    作为字符串的资源名称

    Google API必须使用字符串表示资源名称,除非向后兼容性有问题。资源名称应当像正常文件路径那样处理,并且他们不支持%编码。

    对于资源定义来说,资源名称的第一个字段应当是字符串字段,并被命名为Name

    注意:其他名称相关的字段应当具备避免混淆的命名,比如display\_name, first\_name, last\_name, full\_name

    例如:

    1. service LibraryService {
    2. rpc GetBook(GetBookRequest) returns (Book) {
    3. option (google.api.http) = {
    4. get: "/v1/{name=shelves/*/books/*}"
    5. };
    6. };
    7. rpc CreateBook(CreateBookRequest) returns (Book) {
    8. option (google.api.http) = {
    9. post: "/v1/{parent=shelves/*}/books"
    10. body: "book"
    11. };
    12. };
    13. }
    14. message Book {
    15. //书的资源名称。格式必须是:"shelves/*/books/"
    16. //比如:"shelves/shelf1/books/book2"。
    17. string name = 1;
    18. // ... 其他属性
    19. }
    20. message GetBookRequest {
    21. //书的资源名称。"shelves/shelf1/books/book2"。
    22. string name = 1;
    23. }
    24. message CreateBookRequest {
    25. // 新建书的父资源的资源名称
    26. // 比如"shelves/shelf1".
    27. string parent = 1;
    28. // 要创建的书籍资源,客户端绝不能设置‘Book.name’属性
    29. Book book = 2;
    30. }

    注意:为了资源名称的统一,开头的斜杠绝不能让URL模板变量捕获。例如,必须使用URL模板”/v1/{name=shelves/*/books/*}”而不能使用”/v1{name=/shelves/*/books/*}”.