Nombres de recursos

En las API orientadas a recursos, los recursos son entidades con nombre y los nombres de recursos son sus identificadores. Cada recurso debe tener su propio nombre único. El nombre del recurso está formado por el ID del recurso, los ID de los recursos superiores y el nombre del servicio de API. A continuación, veremos los identificadores de recursos y cómo se crea un nombre de recurso.

Las API de gRPC deben usar URI sin esquema para los nombres de recursos. En general, siguen las convenciones de la URL de REST y se comportan de manera muy similar a las rutas de los archivos de red. Se pueden asignar a las URL de REST con facilidad: consulta la sección Métodos estándar para obtener más información.

Una colección es un tipo especial de recurso que contiene una lista de subrecursos del mismo tipo. Por ejemplo, un directorio es una colección de recursos de archivos. El ID de recurso para una colección se llama ID de colección.

El nombre del recurso se organiza de forma jerárquica mediante ID de colección y de recursos, separados por barras diagonales. Si un recurso contiene un subrecurso, el nombre del subrecurso se forma mediante la especificación del nombre del recurso superior seguido por el ID del subrecurso, de nuevo, separados por barras diagonales.

Ejemplo 1: un servicio de almacenamiento tiene una colección de buckets, en la que cada bucket tiene una colección de objects:

Nombre del servicio de API ID de la colección ID de recurso ID de la colección ID de recurso
//storage.googleapis.com /buckets /bucket-id /objects /object-id

Ejemplo 2: Un servicio de correo electrónico tiene una colección de users Cada usuario tiene un subrecurso settings y el subrecurso settings tiene otros subrecursos, incluido customFrom:

Nombre del servicio de API ID de la colección ID de recurso ID de recurso ID de recurso
//mail.googleapis.com /users /name@example.com /settings /customFrom

Un productor de API puede elegir cualquier valor aceptable para los ID de recursos y de colección siempre que sean únicos dentro de la jerarquía de recursos. Puedes encontrar más indicaciones para elegir los recursos adecuados y los ID de colección a continuación.

Si divides el nombre del recurso, como name.split("/")[n], se pueden obtener los IDs de colección individuales y los de recursos, si se supone que ninguno de los segmentos contiene una barra diagonal.

Nombre completo del recurso

Un URI sin esquema que consta de un nombre de servicio de API compatible con DNS y una ruta de acceso de recurso. La ruta de recursos también se conoce como nombre de recurso relativo. Por ejemplo:

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

El nombre del servicio de API se usa con el fin de que los clientes localicen el extremo del servicio de API; puede ser un nombre de DNS falso solo para servicios internos. Si el nombre del servicio de API es obvio en el contexto, se suelen usar los nombres de recursos relativos.

Nombre de recurso relativo

Una ruta de URI (path-noscheme) sin la “/” inicial. Identifica un recurso dentro del servicio de API. Por ejemplo:

"shelves/shelf1/books/book2"

ID de recurso

Por lo general, un ID de recurso consta de uno o más segmentos de URI no vacíos (segment-nz-nc) que identifican el recurso dentro de su recurso superior, consulta los ejemplos anteriores. El ID de recurso no final en un nombre de recurso debe tener exactamente un segmento de URL, mientras que el ID de recurso final en un nombre de recurso puede tener más de un segmento de URI. Por ejemplo:

ID de la colección ID de recurso
files source/py/parser.py

Los servicios de API deben usar ID de recursos que sean aptos para URL cuando sea posible. Los ID de recursos se deben documentar con claridad, ya sea si los asigna el cliente, el servidor o ambos. Por ejemplo, los clientes asignan los nombres de los archivos, mientras que los servidores asignan los ID de los mensajes de correo electrónico.

ID de la colección

Un segmento de URI no vacío (segment-nz-nc) que identifica el recurso de colección dentro de su recurso superior, consulta los ejemplos anteriores.

Los ID de colección suelen aparecer en las bibliotecas cliente generadas, por eso deben cumplir con los siguientes requisitos:

  • Deben ser identificadores C/C++ válidos.
  • Deben estar en plural escritos en lowerCamel. Si el término no tiene una forma plural adecuada, como “análisis” y “caos”, se debe usar la forma singular.
  • Deben usar términos claros y concisos en inglés.
  • Los términos demasiado generales se deben evitar o calificar. Por ejemplo, se prefiere rowValues en lugar de values. Los siguientes términos se deben evitar sin calificación:
    • elementos
    • entradas
    • instancias
    • artículos
    • objetos
    • recursos
    • tipos
    • valores

Nombre del recurso en comparación con URL

Si bien los nombres completos de los recursos se parecen a las URL normales, no son lo mismo. Un solo recurso se puede exponer mediante diferentes versiones y protocolos de API o extremos de red de API. El nombre completo del recurso no especifica esa información, por eso se debe asignar a una versión y un protocolo de API específicos para su uso efectivo.

Para usar un nombre de recurso completo a través de las API de REST, se debe convertir en una URL de REST. Para eso, es necesario agregar el esquema HTTPS antes del nombre del servicio y la versión principal de la API antes de la ruta del recurso y, también, escapar como URL la ruta del recurso. Por ejemplo:

// 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"

Nombre del recurso como string

Las API de Google deben representar los nombres de recursos con strings simples, a menos que la compatibilidad con las versiones anteriores sea un problema. Los nombres de los recursos deben manejarse como rutas de archivos normales. Cuando se pasa un nombre de recurso entre diferentes componentes, se debe tratar como un valor atómico y no debe tener ninguna pérdida de datos.

En cuanto a las definiciones de recursos, el primer campo debe ser un campo de string para el nombre del recurso y debe llamarse name.

Por ejemplo:

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;
}

Nota: Para mantener la coherencia de los nombres de los recursos, la barra diagonal inicial no se debe capturar por ninguna variable de plantilla de URL. Por ejemplo, la plantilla de URL "/v1/{name=shelves/*/books/*}" debe usarse en lugar de "/v1{name=/shelves/*/books/*}".

Preguntas

P: ¿Por qué no usar ID de recursos para identificar un recurso?

Para cualquier sistema grande, hay muchos tipos de recursos. A fin de usar ID de recursos para identificar un recurso, en realidad usamos una tupla específica del recurso con el objetivo de identificarlo, como (bucket, object) o (user, album, photo). Esto crea varios problemas importantes que se detallan a continuación:

  • Los desarrolladores tienen que entender y recordar esas tuplas anónimas.
  • Por lo general, pasar tuplas es más difícil que pasar strings.
  • Las infraestructuras centralizadas, como los sistemas de registro y control de acceso, no comprenden las tuplas especializadas.
  • Las tuplas especializadas limitan la flexibilidad del diseño de la API, como el suministro de interfaces de API reutilizables. Por ejemplo, las operaciones de ejecución prolongada pueden funcionar con muchas otras interfaces de API porque usan nombres de recursos flexibles.

P.: ¿Por qué el campo del nombre del recurso se llama name en lugar de id?

El campo de nombre del recurso lleva el nombre del concepto de "nombre" del recurso. En general, el concepto de name es confuso para los desarrolladores. Por ejemplo, ¿el nombre del archivo es en realidad solo el nombre o la ruta completa? Mediante la reserva del campo estándar name, los desarrolladores se ven obligados a elegir un término más adecuado, como display_name, title o full_name.

P: ¿Cómo debo generar y analizar nombres de recursos?

Los nombres de recursos se comportan como rutas de archivos. Puedes usar printf() para generar nombres de recursos a partir de los ID de recursos. Puedes usar split() para analizar nombres de recursos en IDs de recursos. Ten en cuenta que algunos ID de recurso finales pueden tener varios segmentos de URI separados por /, como la ruta de acceso del archivo.