Migra de Content API for Shopping a Merchant API

En esta guía, se explica el proceso de migración de Content API for Shopping a la API de Merchant para la administración de datos de la empresa.

Puedes usar esta guía para migrar tu implementación existente de Content API for Shopping a la API de Merchant. Para obtener más información sobre los detalles de la API de Merchant y sus sub-APIs, consulta Diseño de la API de Merchant.

Comenzar

Para comenzar a usar la API de Merchant, cambia las URLs de tus solicitudes al siguiente formato:

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

Para usar la API de Merchant, debes vincular tu cuenta de Merchant Center y tu proyecto de Google Cloud con el método de registro de desarrolladores, de la siguiente manera:

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

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

Para obtener más información, consulta la guía de inicio rápido y la referencia de la API de Merchant.

Mejoras en comparación con Content API for Shopping

La API de Merchant te permite automatizar y optimizar los flujos de trabajo en Merchant Center, y ofrece capacidades mejoradas en comparación con Content API for Shopping.

Casos de uso claves:

  • Administración automática de cuentas
  • Administración automática de productos
  • Administración automática del inventario
  • Informes personalizados

Áreas clave para mejorar:

¿Qué cambió?

  • El pageSize máximo aumentó de 250 a 1,000 filas por llamada a la API.
  • Se corrigió una demora que existía para la inserción de productos, las promociones, las opiniones sobre productos y las opiniones sobre comercios después de DataSources la creación se corrigió.
  • Lanzamiento de una definición actualizada para clickPotentialRank en la productView tabla de la sub-API de informes:
    • La clasificación de los productos en función de clickPotential se normaliza a valores entre 1 y 1,000.
  • El AccountIdAlias en el AccountRelationship recurso permite administrar mejor las estructuras de cuentas complejas. Por ejemplo, los mercados usan un alias definido por el usuario en lugar del ID interno del comercio, como el ID de la cuenta.

Compatibilidad con gRPC

La API de Merchant admite gRPC y REST. Puedes usar gRPC para la API de Merchant y REST para Content API for Shopping al mismo tiempo.

Las bibliotecas cliente de la API de Merchant requieren gRPC.

Para obtener más información, consulta Descripción general de gRPC.

Compatibilidad

En esta guía, se describen los cambios generales que se aplican a toda la API de Merchant.

La API de Merchant está diseñada para funcionar junto con las funciones existentes de Content API for Shopping.

Por ejemplo, puedes usar la API de Merchant Inventories junto con tu implementación existente de Content API for Shopping v2.1 products. Puedes usar Content API for Shopping para subir un nuevo producto local (que vendes en una tienda local) y, luego, usar el recurso LocalInventory de la API de Merchant Inventories para administrar la información en la tienda de ese producto.

Mejoras en comparación con Content API

La API de Merchant mejora Content API en las siguientes áreas:

Considera estos cambios con más detalle.

Control de versiones y sub-APIs

La API de Merchant presenta los conceptos de control de versiones y sub-APIs. Su diseño modular mejora la facilidad de uso, ya que te permite enfocarte en las sub-APIs que necesitas y facilita las migraciones futuras a versiones más recientes. El control de versiones se aplicará con las URLs de tus solicitudes. La estrategia es similar a la experiencia de la API de Google Ads.

Solicitudes más sólidas

Las solicitudes de URL de la API de Merchant requieren más parámetros para llamar a la API de Merchant. Esto incluye el recurso, la versión, el nombre (identificadores) y el método (métodos no estándar). Para obtener más información, consulta Identificadores y ejemplos de cuentas y productos.

Principios de AIP para identificadores

Si bien Content API for Shopping usa IDs para identificar recursos (por ejemplo, merchantId, productId), la API de Merchant usa un name identificador para alinearse con la AIP (consulta Principios de mejora de la API).

El identificador {name} incluye el identificador del recurso y su superior (o potencialmente varios superiores), de modo que {name} sea igual a accounts/{account}/products/{product}.

Todas las llamadas de lectura y escritura muestran el campo name como el identificador del recurso.

{name} también incluye los identificadores de colección accounts/ y products/.

La API de Merchant usa {account} para hacer referencia a un ID de Merchant Center y {product} para hacer referencia a los identificadores de productos.

Por ejemplo, implementa un método getName() para recuperar el name de un recurso y almacenar el resultado como una variable en lugar de construir el name a partir de los IDs del comercio y del recurso.

Este es un ejemplo de cómo usar el campo name en tus llamadas:

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

En la tabla, se muestra cómo cambia la solicitud products.get de Content API for Shopping:

Content API for Shopping API de Merchant
GET https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/products/{productId} GET https://merchantapi.googleapis.com/products/v1/{name}

Para obtener más detalles, consulta Cambios en los identificadores.

Como otro ejemplo, recuperar un producto con el identificador en~US~1234 del ID de Merchant Center 4321 con la API de Merchant se vería de la siguiente manera:

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

donde {name} es igual a accounts/4321/products/en~US~1234. Este nuevo campo de nombre se muestra como el identificador del recurso para todas las llamadas de lectura y escritura en la API de Merchant.

En Content API for Shopping, los dos puntos (:) denotan un delimitador en el nombre del producto, mientras que, en la API de Merchant, la virgulilla (~) realiza esta función. El identificador de la API de Merchant no contiene la parte channel.

Por ejemplo, el ID del producto en Content API for Shopping es el siguiente:

channel:contentLanguage:feedLabel:offerId.

En la API de Merchant, se convierte en lo siguiente:

contentLanguage~feedLabel~offerId.

Campos superiores para recursos secundarios

En la API de Merchant, todos los recursos secundarios tienen el parent campo. Puedes usar el campo parent para especificar el {name} del recurso en el que se insertará el elemento secundario, en lugar de pasar todo el recurso superior. También puedes usar el parent campo con list

Por ejemplo, para enumerar los inventarios locales de un producto determinado, especifica el producto name en el parent campo para el list método. En este caso, el product determinado es el parent de los LocalInventory que se muestran.

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

Para recuperar todos los inventarios locales del producto en~US~1234' y la cuenta 4321 la solicitud se vería de la siguiente manera:

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

El superior es accounts/{account}/products/{product}. Ten en cuenta que, en este caso el localInventories tiene dos superiores incluidos en el identificador de nombre (accounts/ y products/), ya que la cuenta es el superior del recurso de producto.

Enums comunes

El uso de enums comunes proporciona más coherencia.

El campo Destination.DestinationEnum especifica las plataformas en las que se mostrarán tus recursos. DestinationEnum enumera todos los valores disponibles para la segmentación por destino y se unifica en todas las sub-APIs, por ejemplo, para los atributos de promociones.

El ReportingContext.ReportingContextEnum campo representa el contexto al que se aplican los problemas de tu cuenta y de tus productos. Este campo se usa en todos los métodos de informes (por ejemplo, para IssueSeverityPerReportingContext).

Compatibilidad con versiones anteriores

Cuando comiences a usar la API de Merchant, tu integración existente de Content API for Shopping seguirá funcionando sin interrupciones. Para obtener más información, consulta Compatibilidad.

Una vez que migres tus sub-APIs a la API de Merchant, te recomendamos que uses solo la API de Merchant para tus sub-APIs migradas.

Disponibilidad de la llamada de procedimiento remoto (gRPC)

gRPC es la nueva forma recomendada de integrar la API de Merchant.

Sus ventajas incluyen las siguientes:

El procesamiento por lotes personalizado se convierte en procesamiento por lotes integrado

El procesamiento por lotes funciona de manera más eficiente cuando usas llamadas asíncronas. Obtén más información para usar llamadas paralelas para lograr el procesamiento por lotes en la API de Merchant y cómo refactorizar el código para solicitudes simultáneas.

Para acelerar la migración, te recomendamos las bibliotecas cliente.

La API de Merchant no admite el customBatch método que se incluye en Content API for Shopping. En su lugar, consulta Envía varias solicitudes a la vez o ejecuta tus llamadas de forma asíncrona.

En el siguiente ejemplo de Java, se muestra cómo insertar una entrada de producto:

   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.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().setPoolSize(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);
  }
}

Si usas customBatch en Content API y necesitas esta función para la API de Merchant, indícanos por qué en tus comentarios.

Funciones exclusivas

Las funciones futuras solo aparecerán en la API de Merchant. (Habrá algunas excepciones, como la especificación de feed anual de 2025).

Entre las funciones exclusivas de la API de Merchant, se incluyen las siguientes:

Precio

Estos son los cambios en Price en el paquete Merchant Common:

Content API for Shopping API de Merchant
Campo del importe value:string amountMicros:int64
Campo de moneda currency:string currencyCode:string

El importe de Price ahora se registra en micros, en el que 1 millón de micros equivale a la unidad estándar de tu moneda.

En Content API for Shopping, Price era un número decimal en forma de cadena.

El nombre del campo del importe cambió de value a amountMicros.

El nombre del campo de moneda cambió de currency a currencyCode. El formato sigue siendo ISO 4217.

Actualizaciones y anuncios más recientes

Para obtener actualizaciones más detalladas, consulta las notas de la versión específicas de cada sub-API. Para obtener actualizaciones más periódicas y agregadas de la API de Merchant, consulta nuestras actualizaciones más recientes.

Para obtener detalles más específicos y obtener más información sobre la API de Merchant, consulta nuestra descripción general del sitio para desarrolladores y la guía de migración general .

Consulta Diseño de la API de Merchant para obtener detalles sobre la API de Merchant y sus sub-APIs.