Content API for Shopping から Merchant API に移行する

このガイドでは、ビジネスデータ管理のために Content API for Shopping から Merchant API に移行する手順について説明します。

このガイドでは、既存の Content API for Shopping の実装を Merchant API に移行する方法について説明します。Merchant API とそのサブ API の詳細については、Merchant 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 の最大値が、API 呼び出しあたり 250 行から 1,000 行に増加しました。
  • DataSources の作成後に商品挿入、プロモーション、商品レビュー、販売者レビューで発生していた遅延が修正されました。

今後の予定:

  • Reporting サブ APIproductView テーブルで clickPotentialRank の更新された定義をリリースしました。 * clickPotential に基づく商品のランキングが 1 ~ 1,000 の値に正規化されます。
    • clickPotentialRank が低い商品でも、検索クエリの条件を満たす販売者の商品の中ではクリック数の可能性が最も高くなります。これは非互換性のない変更であり、2025 年 7 月 1 日にリリースされる可能性があります。
  • AccountRelationship リソースの AccountIdAlias を使用すると、複雑なアカウント構造をより適切に管理できます。たとえば、ショッピング モールでは、販売者の内部 ID(アカウント ID など)の代わりに、ユーザー定義のエイリアスを使用します。

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 の機能と連携するように設計されています。

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

Content API からの改善点

Merchant API は、次の点で Content API よりも優れています。

これらの変更について詳しく見ていきましょう。

バージョニングとサブ API

Merchant API には、バージョニングサブ API のコンセプトが導入されています。モジュール設計により、必要なサブ API に集中でき、将来の新しいバージョンへの移行が容易になるため、使いやすさが向上します。バージョニングはリクエスト URL に適用されます。この戦略は Google Ads API のエクスペリエンスと似ています。

より堅牢なリクエスト

Merchant API の URL リクエストでは、Merchant API を呼び出すためにさらに多くのパラメータが必要です。これには、リソース、バージョン、名前(識別子)、メソッド(標準以外のメソッド)が含まれます。詳しくは、アカウントとプロダクトの識別子をご覧ください。

ID の AIP 原則

Content API for Shopping では ID(merchantIdproductId など)を使用してリソースを識別しますが、Merchant API では name 識別子を使用して AIP に準拠しています(API 改善原則を参照)。

{name} 識別子には、リソース識別子とその親(または複数の親)が含まれます。{name}accounts/{account}/products/{product} と等しくなります。

読み取り呼び出しと書き込み呼び出しはすべて、リソース識別子として name フィールドを返します。

{name} には、コレクション識別子 accounts/products/ も含まれます。

Merchant API では、Merchant Center ID を参照するために {account} が使用され、商品 ID を参照するために {product} が使用されます。

たとえば、getName() メソッドを実装してリソースから name を取得し、販売者とリソース ID から 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}

詳しくは、識別子の変更をご覧ください。

別の例として、Merchant API を使用して Merchant Center ID 4321 から ID en~US~1234 の商品を取得する場合は、次のようになります。

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/online~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 の商品 ID は次のようになります。

channel:contentLanguage:feedLabel:offerId

Merchant API では次のようになります。

contentLanguage~feedLabel~offerId

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

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

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

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

商品 en~US~1234' とアカウント 4321 のすべてのローカル在庫を取得する場合、リクエストは次のようになります。

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

親は accounts/{account}/products/{product} です。この場合、アカウントが商品リソースの親であるため、localInventories リソースには名前識別子(accounts/products/)に含まれる 2 つの親があります。

共通の列挙型

共通の列挙型を使用すると、一貫性が高まります。

Destination.DestinationEnum フィールドには、リソースを表示するサーフェスを指定します。DestinationEnum は、デスティネーション ターゲティングで使用可能なすべての値を一覧表示し、プロモーション属性など、サブ API 全体で統一されています。

ReportingContext.ReportingContextEnum フィールドは、アカウントと商品の問題が適用されるコンテキストを表します。このフィールドは、レポート方法全体で使用されます(IssueSeverityPerReportingContext など)。

下位互換性

Merchant API の使用を開始しても、既存の Content API for Shopping の統合は中断されることなく引き続き機能します。詳細については、互換性をご覧ください。

サブ API を Merchant API に移行したら、移行したサブ API には Merchant API のみを使用することをおすすめします。

リモート プロシージャ コール(gRPC)の可用性

gRPC は、Merchant API と統合するための新しい推奨方法です。

メリットは次のとおりです。

カスタム バッチ処理が組み込みのバッチ処理になる

バッチ処理は、非同期呼び出しを使用するとより効率的に実行されます。Merchant API でバッチ処理を実現するために並列呼び出しを使用する方法と、同時リクエスト用にコードをリファクタリングする方法について学習します。

移行を迅速に進めるには、クライアント ライブラリを使用することをおすすめします。

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.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 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 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 Pixel だけの機能

今後の機能は Merchant API にのみ追加されます。(2025 年の年間フィード仕様など、例外もあります)。

Merchant API 独自の機能には、以下が含まれます。

  • Reviews API。レビューを使用して、商品とショップの評価を実装、管理します。詳しくは、販売者のレビュー商品のレビューをご覧ください。
  • 通知: アカウントの商品データが変更されたときにプッシュ通知を受け取るよう登録します。

価格

Merchant Common パッケージの Price の変更点は次のとおりです。

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

Price の金額はマイクロ秒単位で記録されるようになりました。100 万マイクロ秒は、通貨の標準単位に相当します。

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

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

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

最新情報とお知らせ

より詳細な更新については、各サブ API 固有のリリースノートをご覧ください。Merchant API の定期的な集計更新については、最新の更新情報をご覧ください。

Merchant API の詳細や、Merchant API についてさらに詳しく知りたい場合は、デベロッパー サイトの概要と移行のガイドをご覧ください。

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