Вы можете использовать службу Google API Discovery Service для создания различных инструментов для работы с API Google. Однако основная цель документа Discovery — предоставить Google возможность создавать клиентские библиотеки на различных языках программирования. В этом документе описывается, как создать собственную клиентскую библиотеку для API Google.
Стабильная и полнофункциональная клиентская библиотека — сложный инструмент, разработка которого может занять месяцы. Однако общие инструкции по созданию простой клиентской библиотеки для API Google можно свести к трем простым шагам:
- Извлечение документа Discovery и построение поверхности API
- Составление запроса
- Совершение вызова и получение ответа
Эти шаги более подробно описаны в следующих разделах. Вы также можете ознакомиться с примером клиента Simple APIs в разделе «Примеры», чтобы увидеть, как эти инструкции соотносятся с кодом.
Получить документ Discovery
Прежде чем приступить к реализации клиентской библиотеки, необходимо соблюсти ряд базовых требований, которые повлияют на ваш подход к разработке. Например, выбранный вами язык программирования может быть типизированным или нетипизированным; если он типизирован, он может быть как статически, так и динамически типизированным. Он может быть компилируемым или интерпретируемым. Эти требования будут определять ваш подход к использованию документа Discovery.
Первая задача разработки — извлечь документ Discovery. Ваша стратегия относительно того, когда именно этот документ будет извлечен, определяется сформулированными вами требованиями. Например, в статически типизированном языке вы можете извлечь документ Discovery на ранних этапах процесса, а затем сгенерировать код для работы с конкретным API, описанным в документе Discovery. Для строго типизированного языка вы можете сгенерировать код и собрать скомпилированную библиотеку. В динамически типизированном языке вы можете лениво конструировать программные структуры для взаимодействия с API «на лету» по мере использования программной поверхности.
Написать запрос
Составление запроса состоит из двух отдельных этапов:
- Составление тела запроса.
- Формирование URL-адреса запроса.
Вам необходимо преобразовать тело запроса (если таковое имеется) из представления, соответствующего языку, в корректный формат. Например, в клиентской библиотеке Java для каждого типа запроса может быть класс, позволяющий типобезопасную обработку данных запроса и сериализуемый в JSON.
Создание URL-адреса запроса — немного более сложный процесс.
Свойство path
каждого метода в API использует синтаксис URI Template v04 . Это свойство может содержать переменные, заключенные в фигурные скобки. Вот пример свойства path
с переменными:
/example/path/var
В приведённом выше пути var
— это переменная. Значение этой переменной берётся из раздела parameters
документа Discovery для данного метода. Каждому имени переменной соответствует значение в объекте parameters
. В приведённом выше примере в разделе parameters
есть параметр с именем var
(и его свойство location
— path
, что указывает на то, что это переменная пути).
При создании запроса необходимо подставить значение var
в URL. Например, если пользователь библиотеки сделает выбор, присвоив var
значение foo
, новый URL будет /example/path/foo
.
Также обратите внимание, что свойство path
представляет собой относительный URI. Чтобы вычислить абсолютный URI, выполните следующие действия:
- Если вы знаете своё местоположение (регион), и в документе Discovery есть свойство
endpoints
, проверьте, присутствует ли ваше местоположение в спискеendpoints
. Если да, выберитеendpointUrl
из спискаendpoints
,location
которых совпадает с вашим. Если в документе Discovery нет свойства
endpoints
или вашего местоположения нет в спискеendpoints
, или вы хотите указать глобальную конечную точку, возьмите свойствоrootUrl
из верхнего уровня документа Discovery.Например, свойство
rootUrl
в документе Discovery для API использования услуг имеет вид:https://serviceusage.googleapis.com/
- Возьмите
servicePath
из верхнего уровня документа Discovery. Например, свойствоservicePath
в документе Discovery для API использования сервиса пустое. Объединим их вместе, чтобы получить:
https://serviceusage.googleapis.com/
Возьмите свойство
path
, разверните его как шаблон URI и объедините результаты этого разворачивания с URI из предыдущего шага. Например, в методеserviceusage.services.enable
API использования сервисов версии 1 значение свойстваpath
равноv1/{+name}:enable
. Таким образом, полный URI для метода выглядит следующим образом:https://serviceusage.googleapis.com/v1/{+name}:enable
Для вызова API использования сервиса ключ API не требуется. Однако, если вызываемый API требует ключ API, вы можете добавить его в строку запроса URI:
REQUEST_URI?key=API_KEY
Позвоните и получите ответ
После отправки запроса необходимо десериализовать ответ в соответствующее языковое представление, уделив внимание обработке возможных ошибок — как в базовом HTTP-транспорте, так и в сообщениях об ошибках, генерируемых службой API. Формат ошибок описан в руководстве Google по стилю JSON .
Примеры
В следующем разделе приведен простой пример клиентской библиотеки API.
Простой клиент API
Ниже приведён пример очень простой клиентской библиотеки, написанной на Python3. Клиент создаёт интерфейс для взаимодействия с API использования сервисов , а затем использует этот интерфейс для включения API Compute Engine ( compute.googleapis.com
) в проекте 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'))
Важнейшими компонентами клиента являются:
- Шаг 1: Извлечение документа Discovery . Документ Discovery для API использования сервиса извлекается и преобразуется в структуру данных. Поскольку Python — язык с динамической типизацией, документ Discovery можно извлечь во время выполнения.
- Шаг 2.a: Построение базового URI . Базовый URI рассчитывается.
- Шаг 2.b: Составление запроса . При вызове метода для коллекции шаблон URI расширяется параметрами, переданными в метод, а параметры с указанием местоположения
query
добавляются в параметры запроса URL. В заключение запрос отправляется на составленный URL с использованием HTTP-метода, указанного в документе Discovery. - Шаг 3.a: Создание клиентской поверхности . Клиентская поверхность строится путем рекурсивного нисходящего обхода разобранного документа Discovery. Для каждого метода в разделе
methods
к объектуCollection
прикрепляется новый метод. Поскольку коллекции могут быть вложенными, мы ищемresources
и рекурсивно создаем объектCollection
для всех его элементов, если таковой найден. Каждая вложенная коллекция также прикрепляется к объектуCollection
в качестве атрибута. - Шаг 3.b: Использование клиента . Это демонстрирует использование созданной поверхности API. Сначала создаётся объект службы на основе документа Discovery, затем API использования служб используется для включения API Compute Engine в проекте
my-project
.