Как перейти с 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:
    • Рейтинг товаров на основе clickPotential нормализуется до значений от 1 до 1000.
  • AccountIdAlias в ресурсе AccountRelationship позволяет эффективнее управлять сложными структурами аккаунтов. Например, торговые площадки используют псевдоним, заданный пользователем, вместо внутреннего идентификатора продавца, такого как идентификатор аккаунта.

Поддержка gRPC

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

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

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

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

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

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

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

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

Merchant API имеет следующие преимущества по сравнению с Content API:

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

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

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

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

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

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

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

Идентификатор {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

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

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. Это новое поле имени возвращается в качестве идентификатора ресурса для всех вызовов чтения и записи в 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 для этих вспомогательных 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, относятся:

Цена

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

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…