Criar uma biblioteca de cliente

É possível usar o serviço de descoberta de APIs do Google para criar várias ferramentas diferentes a serem usadas com as APIs do Google. No entanto, o objetivo principal do documento de descoberta é permitir que o Google crie bibliotecas de cliente em várias linguagens de programação. Neste documento, descrevemos como criar uma biblioteca de cliente personalizada para APIs do Google.

Uma biblioteca de cliente estável e com todos os recursos é uma ferramenta complicada que pode levar meses para ser desenvolvida. No entanto, as instruções gerais para criar uma biblioteca de cliente simples para APIs do Google podem ser divididas em três etapas simples:

  1. Buscar o documento de descoberta e criar a plataforma da API
  2. Criar uma solicitação
  3. Fazer uma chamada e buscar a resposta

Esses níveis são descritos em mais detalhes nas seções a seguir. Confira também o exemplo de cliente de APIs simples na seção "Exemplos" para saber como essas instruções se relacionam com o código.

Buscar o documento de descoberta

Antes de começar a implementar uma biblioteca de cliente, há alguns requisitos básicos que afetam como você avançará no caminho de desenvolvimento. Por exemplo, a linguagem de programação da sua preferência pode ser tipada ou não tipada. Se for tipada, ela poderá ser estaticamente ou dinamicamente tipada. Ela pode ser compilada ou interpretada. Esses requisitos guiarão sua abordagem para consumir e usar o documento de descoberta.

A primeira tarefa de desenvolvimento é buscar o documento de descoberta. Sua estratégia para quando exatamente o documento será buscado é determinada pelos requisitos identificados. Por exemplo, em uma linguagem estaticamente tipada, você pode buscar o documento de descoberta no início do processo e, em seguida, gerar o código para lidar com a API específica descrita pelo documento de descoberta. Para uma linguagem fortemente tipada, você pode gerar código e criar uma biblioteca compilada. Para uma linguagem dinamicamente tipada, é possível criar lentamente as estruturas de programação para interagir com a API em tempo real à medida que a plataforma de programação é usada.

Escrever uma solicitação

Escrever solicitações envolve duas etapas separadas:

  1. Escrever o corpo da solicitação.
  2. Escrever o URL da solicitação.

É necessário converter o corpo da solicitação, se houver, de uma representação de linguagem apropriada para o formato de transmissão correto. Por exemplo, em uma biblioteca de cliente Java, pode haver uma classe para cada tipo de solicitação que permita a manipulação segura de tipos dos dados da solicitação e seja serializável em JSON.

A criação do URL da solicitação é um processo um pouco mais complicado.

A property path de cada método na API usa a sintaxe do Modelo de URI v04. Essa property pode conter variáveis, que estão entre chaves. Veja um exemplo de uma property path com variáveis:

/example/path/var

No caminho acima, var é uma variável. O valor dessa variável vem da seção parameters do documento de descoberta referente a esse método. Cada nome de variável tem um valor correspondente no objeto parameters. No exemplo acima, há um parâmetro chamado var na seção parameters (e respectiva property location é path, para indicar que é uma variável de caminho).

Ao fazer uma solicitação, substitua pelo valor de var no URL. Por exemplo, se o usuário da biblioteca fizer uma escolha que defina var como o valor foo, o novo URL será /example/path/foo.

Além disso, lembre-se de que a property path é um URI relativo. Para calcular o URI absoluto, siga estas etapas:

  1. Se você souber seu local (região) e o documento de descoberta tiver a property endpoints, verifique se esse local está presente na lista endpoints. Nesse caso, extraia o endpointUrl da lista endpoints que tem o location correspondente ao seu.
  2. Se não houver uma property endpoints no documento de descoberta ou se seu local não estiver na lista endpoints ou se você quiser visar o endpoint global, extraia a property rootUrl do nível superior no documento de descoberta.

    Por exemplo, a propriedade rootUrl no documento de descoberta da API Service Usage é:

    https://serviceusage.s3nsapis.fr/
  3. Extraia o servicePath do nível superior no documento de descoberta. Por exemplo, a propriedade servicePath no documento de descoberta da API Service Usage está vazia.
  4. Faça a concatenação para conseguir:

    https://serviceusage.s3nsapis.fr/
  5. Extraia a property path, expanda-a como um modelo de URI e combine os resultados dessa expansão com o URI da etapa anterior. Por exemplo, no método serviceusage.services.enable da API Service Usage v1, o valor da propriedade path é v1/{+name}:enable. O URI completo do método é:

    https://serviceusage.s3nsapis.fr/v1/{+name}:enable

Você não precisa de uma chave de API para chamar a API Service Usage. No entanto, se a API que você está chamando exigir uma chave de API, adicione essa chave à string de consulta do URI:

REQUEST_URI?key=API_KEY

Fazer uma chamada e processar a resposta

Depois de enviar a solicitação, você precisa desserializar a resposta na representação de linguagem apropriada, tomando o cuidado de lidar com as condições de erro que podem ocorrer, tanto no transporte HTTP subjacente quanto nas mensagens de erro geradas pelo serviço da API. O formato dos erros está documentado como parte do Guia de estilo JSON do Google.

Exemplos

A seção a seguir mostra um exemplo simples de uma biblioteca de cliente de APIs.

Cliente de APIs simples

Confira abaixo um exemplo de biblioteca de cliente muito simples escrita em Python 3. O cliente cria uma interface para interagir com a API Service Usage e, em seguida, usa essa interface para ativar a API Compute Engine (compute.googleapis.com) no projeto my-project.

import httplib2
import json
import uritemplate
import urllib

# Step 1: Fetch Discovery document
DISCOVERY_URI = "https://serviceusage.s3nsapis.fr/$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'))

Os componentes principais do cliente são:

  • Etapa 1: buscar o documento de descoberta. O documento de descoberta da API Service Usage é recuperado e analisado em uma estrutura de dados. Como o Python é uma linguagem dinamicamente tipada, o documento de descoberta pode ser buscado no ambiente de execução.
  • Etapa 2.a: criar o URI base. O URI base é calculado.
  • Etapa 2.b: escrever a solicitação. Quando um método é chamado em uma coleção, o modelo de URI é expandido com os parâmetros transmitidos ao método, e os parâmetros com um local de query são colocados nos parâmetros de consulta do URL. Por fim, uma solicitação é enviada para o URL escrito usando o método HTTP especificado no documento de descoberta.
  • Etapa 3.a: criar a plataforma do cliente. A plataforma do cliente é criada por descendência recursiva com o documento de descoberta analisado. Para cada método na seção methods, um novo método é anexado ao objeto Collection. Como as coleções podem ser aninhadas, procuramos por resources e criamos recursivamente um objeto Collection para todos os membros, se algum for encontrado. Cada coleção aninhada também é anexada como um atributo ao objeto Collection.
  • Etapa 3.b: usar o cliente. Demonstramos como usar a plataforma da API criada. Primeiro, um objeto de serviço é criado com base no documento de descoberta. Em seguida, a API Service Usage é usada para ativar a API Compute Engine no projeto my-project.