Nomes dos recursos

Nas APIs orientadas para recursos, os recursos são chamados entidades, e os nomes dos recursos são identificadores deles. Cada recurso precisa ter seu próprio nome exclusivo. O nome do recurso é composto pelo código dele, os códigos de qualquer recurso pai e o nome do serviço da API dele. A seguir, examinaremos os códigos de recursos e como um nome de recurso é construído.

As gRPC APIs usarão URIs sem esquema para nomes de recursos. Eles geralmente seguem as convenções do URL da REST e se comportam como caminhos de arquivos de rede. Eles podem ser facilmente mapeados para os URLs da REST: consulte a seção Métodos padrão para detalhes.

Um conjunto é um tipo especial de recurso que contém uma lista de sub-recursos de tipo idêntico. Por exemplo, um diretório é um conjunto de recursos de arquivos. O código do recurso para um conjunto é chamado de código do conjunto.

O nome do recurso é organizado hierarquicamente usando códigos do conjunto e códigos de recursos, separados por barras. Se um recurso contiver um sub-recurso, o nome dele será formado por meio da especificação do nome do recurso pai seguido pelo código do sub-recurso, separado por barras novamente.

Exemplo 1: um serviço de armazenamento tem uma coleção de buckets, em que cada bucket tem uma coleção de objects:

Nome do serviço da API Código do conjunto Código do recurso Código do conjunto Código do recurso
//storage.googleapis.com buckets /bucket-id /objects /object-id

Exemplo 2: um serviço de e-mail tem um conjunto de users. Cada usuário tem um sub-recurso settings, e o sub-recurso settings tem vários outros recursos, incluindo customFrom:

Nome do serviço da API Código do conjunto Código do recurso Código do recurso Código do recurso
//mail.googleapis.com /users /name@example.com /settings /customFrom

Um produtor de API pode escolher qualquer valor aceitável para códigos de recursos e coleções desde que sejam únicos dentro da hierarquia. Você pode encontrar mais diretrizes para escolher os códigos apropriados dos recursos e coleções abaixo.

Ao dividir o nome do recurso, como name.split("/")[n], é possível conseguir os IDs de coleção individuais e IDs de recursos, supondo que nenhum dos segmentos contenha barras.

Nome completo do recurso

Um URI sem esquema que consiste em um nome de serviço de API compatível com DNS e um caminho de recurso. O caminho do recurso também é conhecido como o nome de recurso relativo. Por exemplo:

"//library.googleapis.com/shelves/shelf1/books/book2"

O nome do serviço da API é para que os clientes localizem o ponto de extremidade do serviço da API. Ele pode ser um nome DNS falso para serviços internos apenas. Se o nome do serviço da API é óbvio a partir do contexto, os nomes de recursos relativos são usados com frequência.

Nome do recurso relativo

Um caminho de URI (path-noscheme) sem o "/" inicial. Ele identifica um recurso no serviço da API. Exemplo:

"shelves/shelf1/books/book2"

Resource ID

Um segmento URI não vazio (segment-nz-nc) que identifica o recurso dentro do recurso pai. Consulte exemplos acima.

O código do recurso de trânsito em um nome de recurso pode ter mais de um segmento de URI. Por exemplo:

Código do conjunto Código do recurso
files /source/py/parser.py

Os serviços de API devem usar códigos de recursos compatíveis com URLs quando possível. Os IDs de recursos precisam ser claramente documentados se são designados pelo cliente, pelo servidor ou por ambos. Por exemplo, os nomes de arquivos geralmente são atribuídos pelos clientes, enquanto os códigos de mensagens de e-mail são atribuídos pelos servidores.

ID da coleção

Um segmento URI não vazio (segment-nz-nc) que identifica o recurso do conjunto no seu recurso pai. Consulte os exemplos acima.

Como os códigos do conjunto aparecem com frequência nas bibliotecas de cliente geradas, eles precisam obedecer aos seguintes requisitos:

  • Precisam ser identificadores de C/C++ válidos.
  • Precisam estar no plural e com letraInicialMinúscula. Se o termo não tiver uma forma plural adequada, como "evidência" e "clima", a forma singular precisará ser usada.
  • Precisam usar termos em inglês claros e concisos.
  • Termos muito gerais devem ser evitados ou qualificados. Por exemplo, rowValues é preferencial a values. Os seguintes termos precisam ser evitados sem qualificação:
    • elements
    • entries
    • instances
    • items
    • objects
    • resources
    • types
    • values

Nome do recurso em comparação com URL

Embora os nomes de recursos completos se pareçam com URLs normais, não são iguais. Um único recurso pode ser exposto por diferentes versões, protocolos ou terminais de rede de API. O nome completo do recurso não especifica essas informações, portanto, precisa ser mapeado para uma versão específica da API e do protocolo dela para uso real.

Para usar um nome de recurso completo por meio das REST APIs, ele precisa ser convertido em um URL da REST por meio da adição do esquema HTTPS antes do nome do serviço, da inserção da versão principal da API antes do caminho do recurso e do escape do URL no caminho do recurso. Por exemplo:

// This is a calendar event resource name.
"//calendar.googleapis.com/users/john smith/events/123"

// This is the corresponding HTTP URL.
"https://calendar.googleapis.com/v3/users/john%20smith/events/123"

Nome do recurso como string

As APIs do Google precisam representar nomes de recursos por strings simples, a menos que a compatibilidade com versões anteriores seja um problema. Os nomes de recursos precisam ser tratados de maneira muito parecida com os caminhos de arquivos normais e não são compatíveis com %-encoding.

Para definições de recursos, o primeiro campo precisa ser um campo de string para o nome do recurso e precisa ser chamado de name.

Exemplo:

service LibraryService {
  rpc GetBook(GetBookRequest) returns (Book) {
    option (google.api.http) = {
      get: "/v1/{name=shelves/*/books/*}"
    };
  };
  rpc CreateBook(CreateBookRequest) returns (Book) {
    option (google.api.http) = {
      post: "/v1/{parent=shelves/*}/books"
      body: "book"
    };
  };
}

message Book {
  // Resource name of the book. It must have the format of "shelves/*/books/*".
  // For example: "shelves/shelf1/books/book2".
  string name = 1;

  // ... other properties
}

message GetBookRequest {
  // Resource name of a book. For example: "shelves/shelf1/books/book2".
  string name = 1;
}

message CreateBookRequest {
  // Resource name of the parent resource where to create the book.
  // For example: "shelves/shelf1".
  string parent = 1;
  // The Book resource to be created. Client must not set the `Book.name` field.
  Book book = 2;
}

Observação: para consistência com os nomes de recursos, a barra não precisa ser capturada por qualquer variável de modelo de URL. Por exemplo, o modelo de URL "/v1/{name=shelves/*/books/*}" deve ser usado em vez de "/v1{name=/shelves/*/books/*}".

Dúvidas

P: Por que não usar códigos de recursos para identificar um recurso?

R: Para qualquer sistema grande, há muitos tipos de recursos. Para usar IDs de recurso para identificar um recurso, usamos uma tupla específica de recurso para identificar um recurso, como (bucket, object) ou (user, album, photo). Isso cria vários problemas grandes:

  • Os desenvolvedores precisam entender e lembrar tais tuplas anônimas.
  • Passar as tuplas geralmente é mais difícil do que passar as strings.
  • As infraestruturas centralizadas, como os sistemas de controle de acesso e geração de registro, não entendem as tuplas especializadas.
  • As tuplas especializadas limitam a flexibilidade do design da API, como fornecer interfaces de API reutilizáveis. Por exemplo, Operações de longa duração podem funcionar com muitas outras interfaces da API porque usam nomes de recursos flexíveis.

P: Por que o campo especial é chamado de name em vez de id?

R: O campo especial tem o nome do conceito de "nome" do recurso. Em geral, descobrimos que o conceito de name é confuso para os desenvolvedores. Por exemplo, o nome do arquivo é realmente apenas o nome ou o caminho completo? Ao reservar o campo padrão name, os desenvolvedores são forçados a escolher um termo mais adequado, como display_name, title ou full_name.