Content API for Shopping の互換性

このガイドでは、Merchant API を既存の Content API for Shopping 実装と統合する方法について説明します。

Merchant API を使用すると、Merchant Center のアカウント、商品、在庫関連の管理ワークフローを自動化できます。Merchant API のユースケースには、次のようなものがあります。

  • アカウント管理の自動化
  • 商品管理の自動化
  • 広告在庫の自動管理
  • カスタム レポートの作成

Content API の改善点

Merchant API は、Content API と比較して次の点で改善されています。

使ってみる

Merchant API とそのサブ API の詳細については、Merchant API の設計をご覧ください。

Merchant API の使用を開始するには、リクエスト URL を次の形式に変更します。

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

詳細については、クイックスタート ガイドと Merchant API のリファレンスをご覧ください。

gRPC のサポート

Merchant API は gRPC と REST をサポートしています。Merchant API には gRPC を、Content API for Shopping には REST を同時に使用できます。

Merchant API のクライアント ライブラリには gRPC が必要です。

詳細については、gRPC を使用するをご覧ください。

互換性

このガイドでは、Merchant API 全体に適用される一般的な変更について説明します。特定の機能の変更については、次のガイドをご覧ください。

Merchant API は、既存の Content API for Shopping v2.1 機能と連携するように設計されています。

たとえば、既存の Content API for Shopping v2.1 products 実装とともに Merchant Inventories API を使用できます。Content API for Shopping を使用して新しいローカル商品(ローカル店舗で販売する商品)をアップロードし、Merchant Inventories API LocalInventory リソースを使用して、その商品の店舗情報を管理できます。

バッチ リクエスト

Merchant API は、Content API for Shopping の customBatch メソッドをサポートしていません。代わりに、複数のリクエストを一括で送信するか、呼び出しを非同期で実行してください。

次のサンプルは、商品入力を挿入する方法を示しています。

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.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1beta.Attributes;
import com.google.shopping.merchant.products.v1beta.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1beta.ProductInput;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1beta.Shipping;
import com.google.shopping.type.Channel.ChannelEnum;
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();

    Attributes attributes =
        Attributes.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("in stock")
            .setCondition("new")
            .setGoogleProductCategory("Media > Books")
            .setGtin(0, "9780007350896")
            .addShipping(shipping)
            .addShipping(shipping2)
            .build();

    return ProductInput.newBuilder()
        .setChannel(ChannelEnum.ONLINE)
        .setContentLanguage("en")
        .setFeedLabel("CH")
        .setOfferId(generateRandomString())
        .setAttributes(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 service settings using the credentials retrieved above.
    ProductInputsServiceSettings productInputsServiceSettings =
        ProductInputsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .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 "FILE", 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);
  }
}

Content API で customBatch を使用していて、Merchant API でこの機能が必要な場合は、フィードバックでその理由をお知らせください。

識別子

Google の API 改善の原則に沿って、Merchant API リソースの ID に変更を加えました。

name が Id に置き換えられます

すべての Merchant API リソースは、一意の識別子として name フィールドを使用します。

呼び出しで name フィールドを使用する方法の例を次に示します。

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

この新しい name フィールドは、Merchant API のすべての読み取り / 書き込み呼び出しのリソース ID として返されます。

たとえば、getName() メソッドを実装してリソースから name を取得し、販売者とリソース ID から name を自分で作成するのではなく、出力を変数として保存します。

子リソースの親フィールド

Merchant API では、すべての子リソースに parent フィールドがあります。parent フィールドを使用すると、親リソース全体を渡す代わりに、子を挿入するリソースの name を指定できます。parent フィールドと list メソッドを使用して、その parent の子リソースを一覧表示することもできます。

たとえば、特定の商品のローカル在庫を一覧表示するには、list メソッドの parent フィールドに商品の name を指定します。この場合、指定された product は、返された LocalInventory リソースの parent です。

Merchant API サブ API で共有される一般的なタイプをいくつか示します。

価格

販売者共通パッケージの Price の変更点は次のとおりです。

Content API Merchant API
金額フィールド value:string amountMicros:int64
通貨フィールド currency:string currencyCode:string

Price の金額はマイクロ単位で記録されます。ここで、100 万マイクロが通貨の標準単位に相当します。

Content API for Shopping では、Price は文字列形式の小数点数でした。

金額フィールド名が value から amountMicros に変更されました

通貨フィールド名が currency から currencyCode に変更されました。形式は ISO 4217 のままです。