Przejście z Content API for Shopping na Merchant API

Z tego przewodnika możesz skorzystać, aby przenieść dotychczasową implementację Content API for Shopping do Merchant API. Więcej informacji o Merchant API i jego interfejsach podrzędnych znajdziesz w artykule Konstrukcja interfejsu Merchant API.

Rozpocznij

Aby zacząć korzystać z interfejsu Merchant API, zmień format adresów URL żądań na ten:

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

Więcej informacji znajdziesz w przewodniku po Merchant Center i dokumentacji API Merchant.

Ulepszenia w stosunku do Content API

Interfejs Merchant API umożliwia automatyzację i usprawnienie procesów w Merchant Center oraz oferuje lepsze możliwości niż Content API.

Najważniejsze zastosowania:

  • Automatyczne zarządzanie kontami
  • Automatyczne zarządzanie produktami
  • Automatyczne zarządzanie zasobami reklamowymi
  • Raportowanie niestandardowe

Najważniejsze obszary ulepszeń:

Obsługa gRPC

Interfejs Merchant API obsługuje protokoły gRPC i REST. Możesz jednocześnie używać interfejsu gRPC dla Merchant API i interfejsu REST dla Content API for Shopping.

Biblioteki klienta interfejsu Merchant API wymagają gRPC.

Więcej informacji znajdziesz w omówieniu gRPC.

Zgodność

Ten przewodnik opisuje ogólne zmiany, które dotyczą całego interfejsu Merchant API. Aby dowiedzieć się więcej o zmianach w poszczególnych funkcjach, w nawigacji znajdź sekcję Przeniesienie z Content API, w której znajdziesz poszczególne przewodniki.

Interfejs Merchant API jest przeznaczony do współpracy z funkcjami Content API for Shopping w wersji 2.1.

Możesz na przykład używać interfejsu Merchant Inventories API razem z obecną implementacją Content API for Shopping w wersji 2.1products. Możesz użyć interfejsu Content API for Shopping, aby przesłać nowy produkt lokalny (który sprzedajesz w lokalnym sklepie), a następnie użyć interfejsu Merchant Inventories API LocalInventory, aby zarządzać informacjami o tym produkcie w sklepie.

Żądania zbiorcze

Interfejs Merchant API nie obsługuje metody customBatch, która jest dostępna w Content API for Shopping. Zamiast tego użyj funkcji Wysyłanie wielu żądań jednocześnie lub wywołaj metody asynchronicznie.

Poniższy przykład pokazuje, jak wstawić dane wejściowe dotyczące produktu.

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);
  }
}

Jeśli używasz interfejsu customBatch w Content API i potrzebujesz tej funkcji w Merchant API, poinformuj nas o tym w opinii.

Identyfikatory

Aby dostosować się do zasad Google dotyczących ulepszania interfejsów API, wprowadziliśmy pewne zmiany w identyfikatorach zasobów interfejsu Merchant API.

name zastępuje Id

Wszystkie zasoby interfejsu Merchant API używają pola name jako unikalnego identyfikatora.

Oto przykład użycia pola name w wywołaniach:

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

To nowe pole name jest zwracane jako identyfikator zasobu we wszystkich wywołaniach odczytu i zapisu w Merchant API.

Na przykład zamiast samodzielnie tworzyć za pomocą metody getName() zmiennej name z identyfikatorów zasobu i sprzedawcy, możesz ją pobrać z zasobu i przechowywać jako zmienną.name

W przypadku żądań HTTP pole name jest pobierane z adresu URL. Zastępuje wartość atrybutu name podana w ciele żądania HTTP.

Ograniczniki

Interfejs Merchant API używa znaków tyldy zamiast dwukropków jako rozdzielaczy.

Poniższa tabela porównuje identyfikator produktu w Content API i Merchant API:

Content API. Merchant API
channel:contentLanguage:feedLabel:offerId. Na przykład: online:en:US:sku123 channel~contentLanguage~feedLabel~offerId. Na przykład: online~en~US~sku123

pola nadrzędne zasobów podrzędnych.

W Merchant API wszystkie zasoby podrzędne mają pole parent. Zamiast przekazywać cały zasób nadrzędny, możesz użyć pola parent, aby określić name zasobu, do którego chcesz wstawić zasób podrzędny. Możesz też użyć pola parent w metodach list, aby wyświetlić zasoby podrzędne tego elementu parent.

Aby na przykład wyświetlić lokalny asortyment danego produktu, określ name produktu w polu parent dla metody list. W tym przypadku podany parametr product to parent zwróconych zasobów LocalInventory.

Typy

Oto kilka typowych typów wspólnych dla interfejsów Merchant API.

Cena

Oto, co się zmieniło w usłudze Price w pakiecie Merchant Common:

Content API. Merchant API
Pole kwoty value:string amountMicros:int64
Pole Waluta currency:string currencyCode:string

Kwota Price jest teraz zapisywana w milionowych częściach, gdzie 1 milion milionowych części jest równy jednostce standardowej Twojej waluty.

W Content API for Shopping parametr Price był liczbą dziesiętną w postaci ciągu znaków.

Nazwa pola „Kwota” zmieniła się z value na amountMicros

Nazwa pola waluty zmieniła się z currency na currencyCode. Format pozostaje bez zmian: ISO 4217.