Przejście z Content API for Shopping na Merchant API

Ten przewodnik wyjaśnia proces migracji z Content API for Shopping na Merchant API do zarządzania firmowymi bazami danych.

Z tego przewodnika dowiesz się, jak przenieść obecną implementację Content API for Shopping na Merchant API. Więcej informacji o Merchant API i jego interfejsach API znajdziesz w artykule Projekt Merchant API.

Rozpocznij

Aby zacząć korzystać z Merchant API, zmień adresy URL żądań na ten format:

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

Aby korzystać z interfejsu Merchant API, musisz połączyć konto Merchant Center z projektem Google Cloud za pomocą metody rejestracji programisty:

POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp

{
  developer_email:"example-email@example.com"
}

Więcej informacji znajdziesz w przewodniku szybkiego startu i dokumentacji Merchant API.

Ulepszenia w porównaniu z Content API for Shopping

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

Kluczowe przypadki użycia:

  • Automatyczne zarządzanie kontami
  • Automatyczne zarządzanie produktami
  • Automatyczne zarządzanie asortymentem
  • Raportowanie niestandardowe

Kluczowe obszary ulepszeń:

Co się zmieniło

  • Maksymalna liczba pageSize wierszy na wywołanie interfejsu API wzrosła z 250 do 1000.
  • Usunięto opóźnienie, które występowało w przypadku wstawiania produktów, promocji, opinii o produktach i opinii o sprzedawcach po utworzeniu DataSources.
  • Wprowadzenie zaktualizowanej definicji clickPotentialRank w productView tabeli w sekcji Interfejs API do raportowania:
    • Ranking produktów na podstawie clickPotential jest normalizowany do wartości z zakresu od 1 do 1000.
  • AccountIdAlias w zasobie AccountRelationship umożliwia lepsze zarządzanie złożonymi strukturami kont. Na przykład platformy handlowe używają zdefiniowanego przez użytkownika aliasu zamiast wewnętrznego identyfikatora sprzedawcy, takiego jak identyfikator konta.

Obsługa gRPC

Merchant API obsługuje gRPC i REST. Możesz jednocześnie używać gRPC w Merchant API i REST w Content API for Shopping.

Biblioteki klienta 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.

Interfejs Merchant API został zaprojektowany tak, aby współpracować z dotychczasowymi funkcjami Content API for Shopping.

Możesz na przykład używać Merchant Inventories API razem z dotychczasową implementacją Content API for Shopping w wersji 2.1.products Możesz użyć Content API for Shopping, aby przesłać nowy produkt lokalny (sprzedawany w sklepie stacjonarnym), a następnie użyć zasobu Merchant Inventories APILocalInventory, aby zarządzać informacjami o tym produkcie w sklepie.

Ulepszenia strukturalne w porównaniu z Content API

Merchant API jest lepszy od Content API w tych obszarach:

Przyjrzyjmy się tym zmianom bliżej.

Obsługa wersji i interfejsy API podrzędne

W Merchant API wprowadzono koncepcje wersjonowania i interfejsów API. Modułowa konstrukcja ułatwia korzystanie z interfejsu API, ponieważ możesz skupić się na potrzebnych Ci interfejsach API i łatwiej przeprowadzać przyszłe migracje do nowszych wersji. Wersjonowanie będzie stosowane w przypadku adresów URL żądań.Strategia jest podobna do interfejsu Google Ads API.

Bardziej złożone żądania

Żądania URL Merchant API wymagają większej liczby parametrów do wywołania Merchant API. Obejmuje to zasób, wersję, nazwę (identyfikatory) i metodę (niestandardowe metody). Więcej informacji znajdziesz w sekcjach Identyfikatory konta i produktu oraz przykłady.

Zasady AIP dotyczące identyfikatorów

Interfejs Content API for Shopping używa identyfikatorów do identyfikowania zasobów (np.merchantId, productId), a Merchant API używa identyfikatoraname, aby zachować zgodność z AIP (patrz zasady ulepszania interfejsu API).

Identyfikator {name} zawiera identyfikator zasobu i jego element nadrzędny (lub potencjalnie wiele elementów nadrzędnych), tak że {name} jest równe accounts/{account}/products/{product}.

Wszystkie wywołania odczytu i zapisu zwracają pole name jako identyfikator zasobu.

{name} zawiera też identyfikatory kolekcji accounts/ i products/.

Interfejs Merchant API używa symbolu {account} do określania identyfikatora w Merchant Center, a symbolu {product} do określania identyfikatorów produktów.

Na przykład zaimplementuj metodę getName(), aby pobrać name z zasobu, i zapisz wynik jako zmienną zamiast samodzielnie tworzyć name na podstawie identyfikatorów sprzedawcy i zasobu.

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

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

Tabela pokazuje, jak zmienia się żądanie do interfejsu Content API for Shoppingproducts.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}

Więcej informacji znajdziesz w sekcji Zmiany identyfikatorów.

Inny przykład: pobieranie produktu z identyfikatorem en~US~1234 z Merchant Center o identyfikatorze w Merchant Center 4321 za pomocą Merchant API wyglądałoby tak:

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

gdzie {name} równa się accounts/4321/products/en~US~1234. To nowe pole nazwy jest zwracane jako identyfikator zasobu we wszystkich wywołaniach odczytu i zapisu w interfejsie Merchant API.

W Content API for Shopping dwukropek (:) oznacza separator w nazwie produktu, a w Merchant API tę funkcję pełni tylda (~). Identyfikator interfejsu Merchant API nie zawiera części channel.

Na przykład identyfikator produktu w Content API for Shopping:

channel:contentLanguage:feedLabel:offerId.

w Merchant API wygląda tak:

contentLanguage~feedLabel~offerId.

Pola nadrzędne w przypadku 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ć element podrzędny. Możesz też użyć pola parent z wartością list.

Aby na przykład wyświetlić listę lokalnych asortymentów dla danego produktu, w polu list metody parent podaj name produktu. W tym przypadku podana wartość product to parent zwróconych zasobów LocalInventory.

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

Aby pobrać wszystkie lokalne asortymenty produktów dla produktu en~US~1234 i konta 4321, żądanie powinno wyglądać tak:

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

Element nadrzędny to accounts/{account}/products/{product}. Pamiętaj, że w tym przypadku zasób localInventories ma 2 elementy nadrzędne uwzględnione w identyfikatorze nazwy (accounts/ i products/), ponieważ konto jest elementem nadrzędnym zasobu produktu.

Typowe wyliczenia

Używanie typowych wyliczeń zapewnia większą spójność.

Pole Destination.DestinationEnum określa platformy, na których mają być wyświetlane zasoby. DestinationEnum zawiera wszystkie dostępne wartości kierowania na miejsce docelowe i jest ujednolicona w różnych interfejsach API, np. w przypadku atrybutów promocji.

Pole ReportingContext.ReportingContextEnum określa kontekst, w którym występują problemy z kontem i informacje o produkcie. To pole jest używane w różnych metodach raportowania (np. w przypadku IssueSeverityPerReportingContext).

Zgodność wsteczna

Gdy zaczniesz korzystać z Merchant API, dotychczasowa integracja z Content API for Shopping będzie nadal działać bez zakłóceń. Więcej informacji znajdziesz w artykule na temat zgodności.

Po przeniesieniu interfejsów API do Merchant API zalecamy używanie tylko Merchant API w przypadku przeniesionych interfejsów API.

Dostępność zdalnego wywoływania procedur (gRPC)

gRPC to nowy, zalecany sposób integracji z Merchant API.

Jego zalety to:

Niestandardowe przetwarzanie wsadowe staje się wbudowanym przetwarzaniem wsadowym

Grupowanie działa wydajniej, gdy używasz wywołań asynchronicznych. Dowiedz się więcej o używaniu wywołań równoległych do osiągania grupowania w interfejsie Merchant API i o tym, jak refaktoryzować kod pod kątem jednoczesnych żądań.

Aby przyspieszyć migrację, zalecamy korzystanie z bibliotek klienta.

Interfejs Merchant API nie obsługuje metody customBatch dostępnej w Content API for Shopping. Zamiast tego zapoznaj się z sekcją Wysyłanie wielu żądań jednocześnie lub wykonuj wywołania asynchronicznie.

Poniższy przykład w języku Java pokazuje, jak wstawić dane wejściowe produktu:

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

Jeśli używasz customBatch w Content API i potrzebujesz tej funkcji w Merchant API, w opinii wyjaśnij, dlaczego.

Wyjątkowe funkcje

Przyszłe funkcje będą dostępne tylko w Merchant API. (Będzie kilka wyjątków, np. roczna specyfikacja pliku danych na 2025 r.).

Funkcje dostępne tylko w Merchant API to:

  • Reviews API. Użyj opinii, aby wdrożyć oceny produktów i sklepu oraz nimi zarządzać. Więcej informacji znajdziesz w artykułach Opinie o sprzedawcy i Opinie o produkcie.
  • Powiadomienia: zarejestruj się, aby otrzymywać powiadomienia push o zmianach na koncie i w danych o produktach.

Cena

Oto co się zmieniło w przypadku Price w pakiecie Merchant Common:

Content API for Shopping Merchant API
Pole kwoty value:string amountMicros:int64
Pole waluty currency:string currencyCode:string

Kwota Price jest teraz rejestrowana w mikrojednostkach, gdzie milion mikrojednostek odpowiada standardowej jednostce waluty.

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

Nazwa pola kwoty została zmieniona z value na amountMicros

Nazwa pola waluty została zmieniona z currency na currencyCode. Format nadal jest zgodny ze standardem ISO 4217.

Najnowsze aktualizacje i ogłoszenia

Bardziej szczegółowe informacje znajdziesz w informacjach o wersjach poszczególnych interfejsów API. Aby otrzymywać regularne zbiorcze aktualizacje Merchant API, zapoznaj się z naszymi najnowszymi aktualizacjami.

Więcej szczegółowych informacji o Merchant API znajdziesz w omówieniu na naszej stronie dla deweloperów oraz w przewodniku po migracji.

Szczegółowe informacje o Merchant API i jego interfejsach API znajdziesz w artykule Projekt Merchant API.