Советы по производительности

В этом документе описаны некоторые методы, которые можно использовать для повышения производительности вашего приложения. В некоторых случаях для иллюстрации представленных идей используются примеры других API или универсальных API. Однако те же концепции применимы к API Google Photos.

Сжатие с помощью gzip

Простой и удобный способ уменьшить пропускную способность, необходимую для каждого запроса, — включить сжатие gzip. Хотя для распаковки результатов требуется дополнительное время процессора, компромисс с сетевыми затратами обычно делает это весьма выгодным.

Чтобы получить ответ в кодировке gzip, вы должны сделать две вещи: установить заголовок Accept-Encoding и изменить свой пользовательский агент, чтобы он содержал строку gzip . Вот пример правильно сформированных HTTP-заголовков для включения сжатия gzip:

Accept-Encoding: gzip
User-Agent: my program (gzip)

Работа с частичными ресурсами

Еще один способ повысить производительность вызовов API — запрашивать только ту часть данных, которая вас интересует. Это позволяет вашему приложению избежать передачи, анализа и хранения ненужных полей, поэтому оно может использовать ресурсы, включая сеть, процессор, и память более эффективна.

Частичный ответ

По умолчанию сервер отправляет обратно полное представление ресурса после обработки запросов. Для повышения производительности вы можете попросить сервер отправлять только те поля, которые вам действительно нужны, и вместо этого получать частичный ответ .

Чтобы запросить частичный ответ, используйте параметр запроса fields , чтобы указать поля, которые вы хотите вернуть. Вы можете использовать этот параметр с любым запросом, который возвращает данные ответа.

Пример

В следующем примере показано использование параметра fields с универсальным (вымышленным) «Демо» API.

Простой запрос: этот HTTP-запрос GET опускает параметр fields и возвращает полный ресурс.

https://www.googleapis.com/demo/v1

Полный ответ ресурса. Полные данные ресурса включают следующие поля, а также многие другие, которые были опущены для краткости.

{
  "kind": "demo",
  ...
  "items": [
  {
    "title": "First title",
    "comment": "First comment.",
    "characteristics": {
      "length": "short",
      "accuracy": "high",
      "followers": ["Jo", "Will"],
    },
    "status": "active",
    ...
  },
  {
    "title": "Second title",
    "comment": "Second comment.",
    "characteristics": {
      "length": "long",
      "accuracy": "medium"
      "followers": [ ],
    },
    "status": "pending",
    ...
  },
  ...
  ]
}

Запрос на частичный ответ: следующий запрос для этого же ресурса использует параметр fields , чтобы значительно уменьшить объем возвращаемых данных.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Частичный ответ: в ответ на приведенный выше запрос сервер отправляет обратно ответ, который содержит только информацию о типе, а также урезанный массив элементов, который включает только информацию о заголовке и длине HTML в каждом элементе.

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Обратите внимание, что ответ представляет собой объект JSON, который включает только выбранные поля и включающие их родительские объекты.

Подробности о форматировании параметра fields рассматриваются далее, а затем более подробная информация о том, что именно возвращается в ответе.

Сводка синтаксиса параметров полей

Формат значения параметра запроса fields во многом основан на синтаксисе XPath. Поддерживаемый синтаксис кратко описан ниже, а дополнительные примеры приведены в следующем разделе.

  • Используйте список, разделенный запятыми, чтобы выбрать несколько полей.
  • Используйте a/b , чтобы выбрать поле b вложенное в поле a ; используйте a/b/c чтобы выбрать поле c вложенное в b .

    Исключение: для ответов API, использующих оболочки «данных», где ответ вложен в объект data , который выглядит как data: { ... } , не включайте « data » в спецификацию fields . Включение объекта данных со спецификацией полей, например data/a/b приводит к ошибке. Вместо этого просто используйте спецификацию fields , например a/b .

  • Используйте дополнительный селектор, чтобы запросить набор определенных подполей массивов или объектов, помещая выражения в круглые скобки " ( ) ".

    Например: fields=items(id,author/email) возвращает только идентификатор элемента и адрес электронной почты автора для каждого элемента массива элементов. Вы также можете указать одно подполе, где fields=items(id) эквивалентны fields=items/id .

  • При необходимости используйте подстановочные знаки при выборе полей.

    Например: fields=items/pagemap/* выбирает все объекты в карте страниц.

Дополнительные примеры использования параметра полей

В приведенных ниже примерах описано, как значение параметра fields влияет на ответ.

Примечание. Как и все значения параметров запроса, значение параметра fields должно быть закодировано в URL-адресе. Для лучшей читаемости в примерах в этом документе кодировка не указана.

Определите поля, которые вы хотите вернуть, или выберите поля .
Значение параметра запроса fields представляет собой список полей, разделенных запятыми, и каждое поле указывается относительно корня ответа. Таким образом, если вы выполняете операцию со списком , ответом является коллекция, обычно включающая массив ресурсов. Если вы выполняете операцию, которая возвращает один ресурс, поля указываются относительно этого ресурса. Если выбранное вами поле является массивом (или является его частью), сервер возвращает выбранную часть всех элементов массива.

Вот несколько примеров на уровне коллекции:
Примеры Эффект
items Возвращает все элементы массива items, включая все поля в каждом элементе, но не другие поля.
etag,items Возвращает поле etag и все элементы массива items.
items/title Возвращает только поле title для всех элементов массива элементов.

Всякий раз, когда возвращается вложенное поле, ответ включает в себя включающие его родительские объекты. Родительские поля не включают в себя другие дочерние поля, если они также не выбраны явно.
context/facets/label Возвращает только поле label для всех членов массива facets , который сам вложен в объект context .
items/pagemap/*/title Для каждого элемента массива items возвращает только поле title (если оно присутствует) всех объектов, которые являются дочерними элементами pagemap .

Вот несколько примеров на уровне ресурсов:
Примеры Эффект
title Возвращает поле title запрошенного ресурса.
author/uri Возвращает подполе uri объекта author в запрошенном ресурсе.
links/*/href
Возвращает поле href всех объектов, являющихся дочерними элементами links .
Запрашивайте только части определенных полей, используя подвыборки .
По умолчанию, если в вашем запросе указаны определенные поля, сервер возвращает объекты или элементы массива целиком. Вы можете указать ответ, который включает только определенные подполя. Вы делаете это, используя синтаксис подвыбора " ( ) ", как в примере ниже.
Пример Эффект
items(title,author/uri) Возвращает только значения title и uri автора для каждого элемента массива items.

Обработка частичных ответов

После того как сервер обрабатывает действительный запрос, включающий параметр запроса fields , он отправляет обратно код состояния HTTP 200 OK вместе с запрошенными данными. Если параметр запроса fields имеет ошибку или по какой-либо причине недействителен, сервер возвращает код состояния HTTP 400 Bad Request вместе с сообщением об ошибке, сообщающим пользователю, что было неправильно с выбором полей (например, "Invalid field selection a/b" ).

Вот пример частичного ответа, показанный во вводном разделе выше. В запросе используется параметр fields , чтобы указать, какие поля следует возвращать.

https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)

Частичный ответ выглядит так:

200 OK
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}

Примечание. Для API, которые поддерживают параметры запроса для разбивки данных на страницы (например, maxResults и nextPageToken ), используйте эти параметры, чтобы уменьшить результаты каждого запроса до управляемого размера. В противном случае выигрыш в производительности, возможный при частичном отклике, может быть не реализован.