Content API for Shopping'den Merchant API'ye geçiş yapma

Mevcut Content API for Shopping uygulamanızı Merchant API'ye taşımak için bu kılavuzu kullanabilirsiniz. Merchant API ve alt API'lerinin ayrıntıları hakkında daha fazla bilgi için Merchant API tasarımı başlıklı makaleyi inceleyin.

Başlayın

Merchant API'yi kullanmaya başlamak için istek URL'lerinizi aşağıdaki biçime getirin:

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

Daha fazla bilgi için hızlı başlangıç kılavuzuna ve Merchant API referansına bakın.

Content API'ye kıyasla iyileştirmeler

Merchant API, Merchant Center'daki iş akışlarını otomatikleştirmenize ve kolaylaştırmanıza olanak tanır ve Content API'ye kıyasla daha gelişmiş özellikler sunar.

Temel kullanım alanları:

  • Otomatik hesap yönetimi
  • Otomatik ürün yönetimi
  • Otomatik envanter yönetimi
  • Özel raporlama

Önemli iyileştirme alanları:

gRPC desteği

Merchant API, gRPC ve REST'i destekler. Merchant API için gRPC'yi ve Content API for Shopping için REST'i aynı anda kullanabilirsiniz.

Merchant API istemci kitaplıkları gRPC gerektirir.

Daha fazla bilgi için gRPC'ye genel bakış başlıklı makaleyi inceleyin.

Uyumluluk

Bu kılavuzda, Merchant API'nin tamamı için geçerli olan genel değişiklikler açıklanmaktadır.

Merchant API, mevcut Content API for Shopping 2.1 özellikleriyle birlikte çalışacak şekilde tasarlanmıştır.

Örneğin, mevcut Content API for Shopping 2.1 sürümünüzle products birlikte Merchant Inventories API'yi kullanabilirsiniz. Yeni bir yerel ürünü (yerel bir mağazada sattığınız) yüklemek için Content API for Shopping'i, ardından bu ürünün mağaza içi bilgilerini yönetmek için Merchant Inventories API LocalInventory kaynağını kullanabilirsiniz.

Toplu istekler

Merchant API, Content API for Shopping'de yer alan customBatch yöntemini desteklemez. Bunun yerine Tek seferde birden fazla istek gönderme başlıklı makaleyi inceleyin veya çağrılarınızı eşzamansız olarak yürütün.

Aşağıdaki örnekte, ürün girişlerinin nasıl asenkron olarak ekleneceği gösterilmektedir.

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")
            .addGtin("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 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'de customBatch kullanıyorsanız ve Merchant API için bu özelliğe ihtiyacınız varsa geri bildiriminizde nedenini bize bildirin.

Tanımlayıcılar

Google'ın API iyileştirme ilkelerine uygunluk sağlamak için Merchant API kaynaklarının tanımlayıcılarında bazı değişiklikler yaptık.

IDENTIFIER kullanımı, kaynak mesajındaki bir alanın kaynağı tanımlamak için kullanıldığını gösterir. Ad alanına eklenir. Kaynak adlarını temsil eden alanlar başlıklı makaleyi inceleyin.

IDENTIFIER değeri, alanın bir oluşturma yöntemi bağlamında giriş olarak kabul edilmediğini (yani OUTPUT_ONLY) belirtirken, kaynağı birincil giriş örneği olarak kabul eden mutasyon yöntemleri için giriş olarak IMMUTABLE olarak kabul edilir ve kabul edilir: Standart Güncelleme.

ad, kimliğin yerini alır

Tüm Merchant API kaynakları, benzersiz tanımlayıcı olarak name alanını kullanır.

Aşağıda, aramalarınızda name alanının nasıl kullanılacağına dair bir örnek verilmiştir:

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

Burada name, accounts/4321/products/online~en~US~1234 değerine eşittir.

Bu yeni name alanı, Merchant API'deki tüm okuma ve yazma çağrıları için kaynak tanımlayıcısı olarak döndürülür.

Örneğin, name değerini bir kaynaktan almak için bir getName() yöntemi uygulayın ve name değerini işletme ve kaynak kimliklerinden kendiniz oluşturmak yerine çıktıyı bir değişken olarak saklayın.

Sınırlayıcılar

Merchant API, ayırıcı olarak iki nokta yerine tilde işareti kullanır.

Aşağıdaki tabloda Content API ve Merchant API'nin ürün kimliği karşılaştırılmıştır:

Content API Merchant API
channel:contentLanguage:feedLabel:offerId. Örneğin, online:en:US:sku123 channel~contentLanguage~feedLabel~offerId. Örneğin, online~en~US~sku123

alt kaynaklar için üst kaynak alanları

Merchant API'de tüm alt kaynaklarda parent alanı bulunur. Üst öğenin tamamını iletmek yerine, alt öğeyi ekleyeceğiniz kaynağın name değerini belirtmek için parent alanını kullanabilirsiniz. Ayrıca, parent alanını list yöntemleriyle kullanarak ilgili parent öğesinin alt kaynaklarını da listeleyebilirsiniz.

Örneğin, belirli bir ürünün yerel envanterlerini listelemek için list yönteminin parent alanında ürünün name değerini belirtin. Bu durumda, verilen product, döndürülen LocalInventory kaynaklarının parent öğesidir.

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

online~en~US~1234 ürünü ve 4321 hesabı için tüm yerel envanterleri almak üzere istek şu şekilde görünür:

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

Burada parent, accounts/{account}/products/{product} değerine eşittir. Bu durumda, hesap ürün kaynağının üst öğesi olduğundan localInventories öğesinin ad tanımlayıcısına iki üst öğe (accounts/ ve products/) dahil edildiğini unutmayın.

Ortak Türler

Merchant API'nin alt API'leri arasında paylaşılan bazı yaygın türler aşağıda verilmiştir.

Destination.DestinationEnum

Kaynaklarınızın hangi yüzeylerde gösterileceğini kontrol etmek için Destination.DestinationEnum alanını kullanın. DestinationEnum alanında, hedef hedefleme için kullanılabilen tüm değerler listelenir. API'ler, DestinationEnum'yi birden fazla alt API'de birleştirir (ör. promosyon özellikleri).

ReportingContext.ReportingContextEnum

ReportingContext.ReportingContextEnum alanı, hesabınız ve ürün sorunlarınızın geçerli olduğu bağlamı temsil eder. Bu alan, raporlama yöntemlerinde (ör. IssueSeverityPerReportingContext için) kullanılır.

Fiyat

Merchant Common paketinde Price için yapılan değişiklikleri aşağıda bulabilirsiniz:

Content API Merchant API
Tutar alanı value:string amountMicros:int64
Para birimi alanı currency:string currencyCode:string

Price tutarı artık mikro cinsinden kaydedilir. 1 milyon mikro, para biriminizin standart birimine eşdeğerdir.

Content API for Shopping'de Price, dize biçiminde bir ondalık sayıydı.

Tutar alanı adı value yerine amountMicros olarak değiştirildi

Para birimi alanı adı currency yerine currencyCode olarak değiştirildi. Biçim ISO 4217 olarak kalır.