Как перейти с Content API for Shopping на Merchant API

В этом руководстве рассказывается, как перейти с Content API for Shopping на Merchant API для управления коммерческими данными.

Это руководство поможет вам перейти с Content API for Shopping на Merchant API. Подробнее о Merchant API и его дочерних API…

Начать

Чтобы начать использовать Merchant API, измените URL запросов на следующий формат:

https://merchantapi.googleapis.com/{SUB_API}/{VERSION}/{RESOURCE_NAME}:{METHOD}…

Чтобы использовать Merchant API, необходимо связать аккаунт Merchant Center и облачный проект Google Cloud, выполнив регистрацию разработчика. Для этого сделайте следующее:

POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp

{
  developer_email:"example-email@example.com"
}

Дополнительную информацию можно найти в кратком руководстве и документации по Merchant API.

Преимущества по сравнению с Content API for Shopping

Merchant API позволяет автоматизировать и оптимизировать рабочие процессы в Merchant Center и предлагает расширенные возможности по сравнению с Content API for Shopping.

Основные примеры использования:

  • Автоматизированное управление аккаунтом
  • Автоматизированное управление товарами
  • Автоматизированное управление инвентарем
  • Специальные отчеты

Основные области для улучшения:

Что изменилось

  • Максимальное значение pageSize увеличено с 250 до 1000 строк на вызов API.
  • Устранена задержка, которая возникала при добавлении товаров, промоакций, отзывов о товарах и продавцах после создания DataSources.
  • Обновлено определение clickPotentialRank в таблице productView в разделе Reporting sub-API:
    • Рейтинг товаров на основе clickPotential нормализуется до значений от 1 до 1000.
  • Поле AccountIdAlias в ресурсе AccountRelationship позволяет эффективнее управлять сложными структурами аккаунтов. Например, торговые площадки используют псевдоним, заданный пользователем, вместо внутреннего идентификатора продавца, такого как идентификатор аккаунта.

Поддержка gRPC

Merchant API поддерживает gRPC и REST. Вы можете одновременно использовать gRPC для Merchant API и REST для Content API for Shopping.

Для работы с клиентскими библиотеками Merchant API требуется gRPC.

Подробнее об API gRPC…

Совместимость

В этом руководстве описаны общие изменения, которые касаются всего Merchant API.

Merchant API разработан для работы вместе с существующими функциями Content API for Shopping.

Например, вы можете использовать Merchant Inventories API вместе с существующей реализацией Content API for Shopping версии 2.1 products. Например, вы можете загрузить новый товар местного ассортимента (который продается в обычном магазине) с помощью Content API for Shopping, а затем использовать ресурс LocalInventory Merchant Inventories API, чтобы управлять информацией о товаре в магазине.

Структурные улучшения по сравнению с Content API

Merchant API отличается от Content API следующим:

Рассмотрим эти изменения подробнее.

Управление версиями и дочерние API

В Merchant API используются концепции управления версиями и дочерних API. Модульная структура упрощает работу, позволяя сосредоточиться на нужных дополнительных API и облегчая переход на новые версии в будущем. Управление версиями будет применяться к URL запросов. Эта стратегия похожа на ту, которая используется в Google Ads API.

Более надежные запросы

Для вызова Merchant API в URL-запросах требуется больше параметров. В частности, это касается ресурса, версии, названия (идентификаторов) и метода (нестандартных методов). Подробнее об идентификаторах аккаунтов и товаров и примерах…

Принципы AIP в отношении идентификаторов

В Content API for Shopping для идентификации ресурсов используются идентификаторы (например, merchantId, productId), а в Merchant API – идентификатор name, который соответствует AIP (см. Принципы улучшения API).

Идентификатор {name} включает идентификатор ресурса и его родительского объекта (или нескольких родительских объектов), поэтому {name} равен accounts/{account}/products/{product}.

Все вызовы чтения и записи возвращают поле name в качестве идентификатора ресурса.

{name} также включает идентификаторы коллекций accounts/ и products/.

В Merchant API {account} используется для обозначения идентификатора Merchant Center, а {product} – для обозначения идентификаторов товаров.

Например, реализуйте метод getName(), чтобы получить name из ресурса, и сохраните выходные данные в виде переменной, а не создавайте name из идентификаторов продавца и ресурса самостоятельно.

Вот пример того, как использовать поле name в вызовах:

   POST https://merchantapi.googleapis.com/inventories/v1/{PARENT}/regionalInventories:insert

В таблице ниже показано, как меняется запрос products.get Content API for Shopping.

Content API for Shopping Merchant API
GET https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/products/{productId} GET https://merchantapi.googleapis.com/products/v1/{name}

Подробнее об изменениях в идентификаторах…

Вот ещё один пример. Чтобы получить товар с идентификатором en~US~1234 из аккаунта Merchant Center с идентификатором 4321 с помощью Merchant API, нужно выполнить следующий запрос:

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/en~US~1234

где {name} равно accounts/4321/products/en~US~1234. Это новое поле name возвращается в качестве идентификатора ресурса для всех вызовов чтения и записи в Merchant API.

В Content API for Shopping в качестве разделителя в названии товара используется двоеточие (:), а в Merchant API – тильда (~). Идентификатор Merchant API не содержит часть channel.

Пример идентификатора товара в Content API for Shopping:

channel:contentLanguage:feedLabel:offerId.

в Merchant API будет выглядеть следующим образом:

contentLanguage~feedLabel~offerId.

Родительские поля для дочерних ресурсов

В Merchant API у всех дочерних ресурсов есть поле parent. Вместо передачи всего родительского ресурса вы можете использовать поле parent, чтобы указать {name} ресурса, в который нужно вставить дочерний ресурс. Вы также можете использовать поле parent с list.

Например, чтобы получить список местных ассортиментов для определенного товара, укажите name товара в поле parent для метода list. В этом случае product – это parent возвращенных ресурсов LocalInventory.

    GET
    https://merchantapi.googleapis.com/inventories/v1/{parent}/localInventories

Чтобы получить все данные о местном ассортименте для товара en~US~1234 и аккаунта 4321, запрос должен выглядеть следующим образом:

    GET
    https://merchantapi.googleapis.com/inventories/v1/accounts/4321/products/en~US~1234/localInventories

Родительский элемент: accounts/{account}/products/{product}. Обратите внимание, что в этом случае у ресурса localInventories есть два родительских ресурса, включенных в идентификатор имени (accounts/ и products/), поскольку аккаунт является родительским ресурсом для ресурса товара.

Общие перечисления

Использование общих перечислений обеспечивает большую согласованность.

Поле Destination.DestinationEnum определяет, на каких платформах будут показываться ваши ресурсы. DestinationEnum содержит список всех доступных значений для таргетинга на целевые сервисы и является общим для всех дочерних API, например для атрибутов промоакций.

Поле ReportingContext.ReportingContextEnum представляет контекст, к которому относятся проблемы с аккаунтом и товарами. Это поле используется в разных методах создания отчетов (например, для IssueSeverityPerReportingContext).

Обратная совместимость

Когда вы начнете использовать Merchant API, существующая интеграция с Content API for Shopping продолжит работать без перебоев. Подробнее о совместимости…

После переноса дочерних API в Merchant API рекомендуем использовать для них только Merchant API.

Доступность вызова удаленных процедур (gRPC)

gRPC – это новый рекомендуемый способ интеграции с Merchant API.

Преимущества:

Специальные пакетные запросы становятся встроенными

Пакетная обработка более эффективна при использовании асинхронных вызовов. Подробнее о том, как использовать параллельные вызовы для пакетных запросов в Merchant API и как провести рефакторинг кода для параллельных запросов…

Чтобы ускорить переход, рекомендуем использовать клиентские библиотеки.

Merchant API не поддерживает метод customBatch, который есть в Content API for Shopping. Вместо этого отправляйте несколько запросов одновременно или выполняйте вызовы асинхронно.

.

Ниже приведен пример кода на Java, который показывает, как добавить товар.

   import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutureCallback;
import com.google.api.core.ApiFutures;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.grpc.ChannelPoolSettings;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1.Availability;
import com.google.shopping.merchant.products.v1.Condition;
import com.google.shopping.merchant.products.v1.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductAttributes;
import com.google.shopping.merchant.products.v1.ProductInput;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1.Shipping;
import com.google.shopping.type.Price;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/** This class demonstrates how to insert a product input */
public class InsertProductInputAsyncSample {

  private static String getParent(String accountId) {
    return String.format("accounts/%s", accountId);
  }

  private static String generateRandomString() {
    String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random();
    StringBuilder sb = new StringBuilder(8);
    for (int i = 0; i < 8; i++) {
      sb.append(characters.charAt(random.nextInt(characters.length())));
    }
    return sb.toString();
  }

  private static ProductInput createRandomProduct() {
    Price price = Price.newBuilder().setAmountMicros(33_450_000).setCurrencyCode("USD").build();

    Shipping shipping =
        Shipping.newBuilder().setPrice(price).setCountry("GB").setService("1st class post").build();

    Shipping shipping2 =
        Shipping.newBuilder().setPrice(price).setCountry("FR").setService("1st class post").build();

    ProductAttributes attributes =
        ProductAttributes.newBuilder()
            .setTitle("A Tale of Two Cities")
            .setDescription("A classic novel about the French Revolution")
            .setLink("https://exampleWebsite.com/tale-of-two-cities.html")
            .setImageLink("https://exampleWebsite.com/tale-of-two-cities.jpg")
            .setAvailability(Availability.IN_STOCK)
            .setCondition(Condition.NEW)
            .setGoogleProductCategory("Media > Books")
            .addGtins("9780007350896")
            .addShipping(shipping)
            .addShipping(shipping2)
            .build();

    return ProductInput.newBuilder()
        .setContentLanguage("en")
        .setFeedLabel("CH")
        .setOfferId(generateRandomString())
        .setProductAttributes(attributes)
        .build();
  }

  public static void asyncInsertProductInput(Config config, String dataSource) throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates a channel provider. This provider manages a pool of gRPC channels
    // to enhance throughput for bulk operations. Each individual channel in the pool
    // can handle up to approximately 100 concurrent requests.
    //
    // Channel: A single connection pathway to the service.
    // Pool: A collection of multiple channels managed by this provider.
    //   Requests are distributed across the channels in the pool.
    //
    // We recommend estimating the number of concurrent requests you'll make, divide by 50 (50%
    // utilization of channel capacity), and set the pool size to that number.
    InstantiatingGrpcChannelProvider channelProvider =
        InstantiatingGrpcChannelProvider.newBuilder()
            .setChannelPoolSettings(ChannelPoolSettings.staticallySized(30))
            .build();

    // Creates service settings using the credentials retrieved above.
    ProductInputsServiceSettings productInputsServiceSettings =
        ProductInputsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .setTransportChannelProvider(channelProvider)
            .build();

    // Creates parent to identify where to insert the product.
    String parent = getParent(config.getAccountId().toString());

    // Calls the API and catches and prints any network failures/errors.
    try (ProductInputsServiceClient productInputsServiceClient =
        ProductInputsServiceClient.create(productInputsServiceSettings)) {

      // Creates five insert product input requests with random product IDs.
      List<InsertProductInputRequest> requests = new ArrayList<>(5);
      for (int i = 0; i < 5; i++) {
        InsertProductInputRequest request =
            InsertProductInputRequest.newBuilder()
                .setParent(parent)
                // You can only insert products into datasource types of Input "API", and of Type
                // "Primary" or "Supplemental."
                // This field takes the `name` field of the datasource.
                .setDataSource(dataSource)
                // If this product is already owned by another datasource, when re-inserting, the
                // new datasource will take ownership of the product.
                .setProductInput(createRandomProduct())
                .build();

        requests.add(request);
      }

      System.out.println("Sending insert product input requests");
      List<ApiFuture<ProductInput>> futures =
          requests.stream()
              .map(
                  request ->
                      productInputsServiceClient.insertProductInputCallable().futureCall(request))
              .collect(Collectors.toList());

      // Creates callback to handle the responses when all are ready.
      ApiFuture<List<ProductInput>> responses = ApiFutures.allAsList(futures);
      ApiFutures.addCallback(
          responses,
          new ApiFutureCallback<List<ProductInput>>() {
            @Override
            public void onSuccess(List<ProductInput> results) {
              System.out.println("Inserted products below");
              System.out.println(results);
            }

            @Override
            public void onFailure(Throwable throwable) {
              System.out.println(throwable);
            }
          },
          MoreExecutors.directExecutor());

    } catch (Exception e) {
      System.out.println(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    // Identifies the data source that will own the product input.
    String dataSource = "accounts/" + config.getAccountId() + "/dataSources/{datasourceId}";

    asyncInsertProductInput(config, dataSource);
  }
}

Если вы используете customBatch в Content API и вам нужна эта функция в Merchant API, сообщите нам об этом в отзыве.

Эксклюзивные функции

Новые функции будут появляться только в Merchant API. (за некоторыми исключениями, такими как ежегодная спецификация фидов 2025 года).

Эксклюзивные функции Merchant API

Цена

Вот что изменилось для Price в пакете Merchant Common:

Content API for Shopping Merchant API
Поле для ввода суммы value:string amountMicros:int64
Поле валюты currency:string currencyCode:string

Теперь сумма Price указывается в микроединицах, где 1 миллион микроединиц эквивалентен стандартной единице вашей валюты.

В Content API for Shopping атрибут Price был десятичным числом в виде строки.

Название поля суммы изменено с value на amountMicros.

Название поля валюты изменено с currency на currencyCode. Формат остается прежним – ISO 4217.

Последние новости и объявления

Более подробную информацию можно найти в примечаниях к выпуску для каждого дочернего API. Чтобы узнавать о регулярных обновлениях Merchant API, следите за новостями.

Более подробную информацию о Merchant API можно найти на нашем сайте для разработчиков в обзоре и руководстве по переносу.

Подробнее о Merchant API и его дочерних API…