Crear una biblioteca de cliente

Puedes usar el servicio de descubrimiento de APIs de Google para crear varias herramientas diferentes que se puedan usar con las APIs de Google. Sin embargo, el objetivo principal del documento de descubrimiento es permitir que Google cree bibliotecas de cliente en varios lenguajes de programación. En este documento se describe cómo puedes crear una biblioteca de cliente personalizada para las APIs de Google.

Una biblioteca de cliente estable y con todas las funciones es una herramienta compleja que puede tardar meses en desarrollarse. Sin embargo, las instrucciones generales para crear una biblioteca de cliente sencilla para las APIs de Google se pueden dividir en tres pasos sencillos:

  1. Obtener el documento de descubrimiento y crear la superficie de la API
  2. Redactar una solicitud
  3. Hacer una llamada y obtener la respuesta

Estos pasos se describen con más detalle en las siguientes secciones. También puedes consultar el ejemplo de cliente de APIs simples en la sección Ejemplos para ver cómo se asignan estas instrucciones al código.

Obtener el documento de descubrimiento

Antes de empezar a implementar una biblioteca de cliente, debes cumplir algunos requisitos básicos que influyen en el proceso de desarrollo. Por ejemplo, el lenguaje de programación que elijas puede ser tipado o no tipado. Si es tipado, puede ser estático o dinámico. Puede compilarse o interpretarse. Estos requisitos te ayudarán a consumir y usar el documento de descubrimiento.

La primera tarea de desarrollo es obtener el documento de Discovery. La estrategia que sigas para determinar exactamente cuándo se debe obtener el documento depende de los requisitos que hayas identificado. Por ejemplo, en un lenguaje con tipado estático, puedes obtener el documento de descubrimiento al principio del proceso y, a continuación, generar código para gestionar la API específica descrita en el documento de descubrimiento. En el caso de un lenguaje con tipado fuerte, puedes generar código y crear una biblioteca compilada. En el caso de los lenguajes con tipado dinámico, puedes crear las estructuras de programación de forma diferida para interactuar con la API sobre la marcha, a medida que se usa la superficie de programación.

Redactar una solicitud

Para crear una solicitud, se deben seguir dos pasos:

  1. Redacción del cuerpo de la solicitud.
  2. Construir la URL de la solicitud.

Debes convertir el cuerpo de la solicitud, si lo hay, de una representación adecuada para el idioma al formato de cable correcto. Por ejemplo, en una biblioteca de cliente de Java, puede haber una clase para cada tipo de solicitud que permita la manipulación de los datos de la solicitud con seguridad de tipos y que se pueda serializar en JSON.

La creación de la URL de solicitud es un proceso ligeramente más complicado.

La propiedad path de cada método de la API usa la sintaxis de plantilla de URI v04. Esta propiedad puede contener variables, que están entre llaves. A continuación, se muestra un ejemplo de una propiedad path con variables:

/example/path/var

En la ruta anterior, var es una variable. El valor de esta variable procede de la sección parameters del documento de Discovery de ese método. Cada nombre de variable tiene un valor correspondiente en el objeto parameters. En el ejemplo anterior, hay un parámetro llamado var en la sección parameters (y su propiedad location es path, para indicar que es una variable de ruta).

Cuando haga una solicitud, debe sustituir el valor de var en la URL. Por ejemplo, si el usuario de la biblioteca toma una decisión que asigna el valor foo a var, la nueva URL será /example/path/foo.

Ten en cuenta también que la propiedad path es un URI relativo. Para calcular el URI absoluto, sigue estos pasos:

  1. Si conoces tu ubicación (región) y el documento de descubrimiento tiene la propiedad endpoints, comprueba si tu ubicación está en la lista endpoints. Si es así, elige el endpointUrl de la lista endpoints cuyo location coincida con el tuyo.
  2. Si no hay ninguna propiedad endpoints en el documento de descubrimiento o tu ubicación no está en la lista endpoints, o bien quieres orientar el endpoint global, obtén la propiedad rootUrl del nivel superior del documento de descubrimiento.

    Por ejemplo, la propiedad rootUrl del documento de descubrimiento de la API Service Usage es la siguiente:

    https://serviceusage.googleapis.com/
  3. Obtén el servicePath del nivel superior del documento de descubrimiento. Por ejemplo, la propiedad servicePath del documento de descubrimiento de la API Service Usage está vacía.
  4. Concatenarlas para obtener lo siguiente:

    https://serviceusage.googleapis.com/
  5. Obtén la propiedad path, expándela como plantilla de URI y combina los resultados de esa expansión con el URI del paso anterior. Por ejemplo, en el método serviceusage.services.enable de la API Service Usage v1, el valor de la propiedad path es v1/{+name}:enable. Por lo tanto, el URI completo del método es el siguiente:

    https://serviceusage.googleapis.com/v1/{+name}:enable

No necesitas una clave de API para llamar a la API de Uso de Servicio. Sin embargo, si la API a la que llamas requiere una clave de API, puedes añadir la clave de API a la cadena de consulta del URI:

REQUEST_URI?key=API_KEY

Hacer una llamada y gestionar la respuesta

Después de enviar la solicitud, debes deserializar la respuesta en la representación del lenguaje adecuada y gestionar las condiciones de error que puedan producirse, tanto en el transporte HTTP subyacente como en los mensajes de error generados por el servicio de la API. El formato de los errores se describe en la guía de estilo JSON de Google.

Ejemplos

En la siguiente sección se muestra un ejemplo sencillo de una biblioteca de cliente de APIs.

Cliente de APIs simples

A continuación, se muestra un ejemplo de una biblioteca de cliente muy sencilla escrita en Python3. El cliente crea una interfaz para interactuar con la API de Uso de Servicio y, a continuación, usa esa interfaz para habilitar la API de Compute Engine (compute.googleapis.com) en el proyecto my-project.

import httplib2
import json
import uritemplate
import urllib

# Step 1: Fetch Discovery document
DISCOVERY_URI = "https://serviceusage.googleapis.com/$discovery/rest?version=v1"
h = httplib2.Http()
resp, content = h.request(DISCOVERY_URI)
discovery = json.loads(content)
location = None # Set this to your location if appropriate
use_global_endpoint = True # Set this to False if you want to target the endpoint for your location

# Step 2.a: Construct base URI
BASE_URL = None
if not use_global_endpoint and location:
  if discovery['endpoints']:
    BASE_URL = next((item['endpointUrl'] for item in discovery['endpoints'] if item['location'] == location), None)
if not BASE_URL:
  BASE_URL = discovery['rootUrl']
BASE_URL += discovery['servicePath']

class Collection(object): pass

def createNewMethod(name, method):
  # Step 2.b Compose request
  def newMethod(**kwargs):
    body = kwargs.pop('body', None)
    url = urllib.parse.urljoin(BASE_URL, uritemplate.expand(method['path'], kwargs))
    for pname, pconfig in method.get('parameters', {}).items():
      if pconfig['location'] == 'path' and pname in kwargs:
        del kwargs[pname]
    if kwargs:
      url = url + '?' + urllib.parse.urlencode(kwargs)
    return h.request(url, method=method['httpMethod'], body=body,
                     headers={'content-type': 'application/json'})

  return newMethod

# Step 3.a: Build client surface
def build(discovery, collection):
  for name, resource in discovery.get('resources', {}).items():
    setattr(collection, name, build(resource, Collection()))
  for name, method in discovery.get('methods', {}).items():
    setattr(collection, name, createNewMethod(name, method))
  return collection

# Step 3.b: Use the client
service = build(discovery, Collection())
print (serviceusage.services.enable(name='projects/my-project/services/compute.googleapis.com'))

Los componentes críticos del cliente son los siguientes:

  • Paso 1: Obtén el documento de Discovery. Se obtiene el documento de descubrimiento de la API Service Usage y se analiza en una estructura de datos. Como Python es un lenguaje de tipado dinámico, el documento de Discovery se puede obtener en tiempo de ejecución.
  • Paso 2a: Construye el URI base. Se calcula el URI base.
  • Paso 2b: Redacta la solicitud. Cuando se llama a un método en una colección, la plantilla de URI se amplía con los parámetros que se han pasado al método y los parámetros con una ubicación de query se colocan en los parámetros de consulta de la URL. Por último, se envía una solicitud a la URL compuesta mediante el método HTTP especificado en el documento de descubrimiento.
  • Paso 3a: Crea la superficie del cliente. La superficie del cliente se crea descendiendo de forma recursiva sobre el documento de descubrimiento analizado. Por cada método de la sección methods, se adjunta un nuevo método al objeto Collection. Como las colecciones se pueden anidar, buscamos resources y creamos de forma recursiva un objeto Collection para todos sus miembros si se encuentra uno. Cada colección anidada también se adjunta como atributo al objeto Collection.
  • Paso 3b: Usa el cliente. En este ejemplo se muestra cómo se usa la superficie de la API creada. Primero, se crea un objeto de servicio a partir del documento de descubrimiento. Después, se usa la API Service Usage para habilitar la API Compute Engine en el proyecto my-project.