ย้ายข้อมูลจาก 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 สำหรับ Shopping

กรณีการใช้งานหลัก

  • การจัดการบัญชีอัตโนมัติ
  • การจัดการผลิตภัณฑ์อัตโนมัติ
  • การจัดการพื้นที่โฆษณาอัตโนมัติ
  • การรายงานที่กำหนดเอง

ด้านที่ต้องปรับปรุง

มีอะไรเปลี่ยนแปลงบ้าง

  • pageSize สูงสุดเพิ่มขึ้นจาก 250 เป็น 1,000 แถวต่อการเรียก API
  • ความล่าช้าในการแทรกผลิตภัณฑ์ โปรโมชัน รีวิวผลิตภัณฑ์ และรีวิวผู้ขายหลังจากสร้าง DataSources ได้รับการแก้ไขแล้ว
  • เปิดตัวคำจำกัดความที่อัปเดตแล้วสำหรับ clickPotentialRank ในตาราง productView ภายใต้ API ย่อยการรายงาน
    • การจัดอันดับผลิตภัณฑ์ตาม clickPotential จะได้รับการปรับให้เป็นค่า ระหว่าง 1 ถึง 1000
  • AccountIdAlias ในแหล่งข้อมูล AccountRelationship ช่วยให้จัดการโครงสร้างบัญชีที่ซับซ้อนได้ดียิ่งขึ้น ตัวอย่างเช่น มาร์เก็ตเพลสใช้นามแฝงที่ผู้ใช้กำหนดแทนรหัสภายในของผู้ขาย เช่น รหัสบัญชี

รองรับ gRPC

Merchant API รองรับ gRPC และ REST คุณใช้ gRPC สำหรับ Merchant API และ REST สำหรับ Content API for Shopping พร้อมกันได้

ไลบรารีของไคลเอ็นต์ Merchant API ต้องใช้ gRPC

ดูข้อมูลเพิ่มเติมได้ที่ ภาพรวม gRPC

ความเข้ากันได้

คู่มือนี้อธิบายการเปลี่ยนแปลงทั่วไปที่มีผลกับ Merchant API ทั้งหมด

Merchant API ออกแบบมาให้ทำงานร่วมกับฟีเจอร์ Content API for Shopping ที่มีอยู่

เช่น คุณสามารถใช้ Merchant Inventories API ควบคู่ไปกับการติดตั้งใช้งาน Content API for Shopping v2.1 products ที่มีอยู่ คุณอาจใช้ Content API for Shopping เพื่ออัปโหลดผลิตภัณฑ์ใหม่ในร้านค้า (ที่คุณขายในร้านค้า) จากนั้นใช้แหล่งข้อมูล Merchant Inventories API LocalInventory เพื่อจัดการข้อมูลในร้านค้าสำหรับผลิตภัณฑ์นั้น

การปรับปรุงโครงสร้างผ่าน Content API

Merchant API มีประสิทธิภาพดีกว่า Content API ในด้านต่อไปนี้

มาดูรายละเอียดเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงเหล่านี้กัน

การกำหนดเวอร์ชันและ API ย่อย

Merchant API ขอแนะนำแนวคิดเรื่อง การกำหนดเวอร์ชันและ API ย่อย การออกแบบแบบโมดูลช่วยเพิ่มความสะดวกในการใช้งาน โดยให้คุณมุ่งเน้นที่ API ย่อยที่ต้องการและช่วยให้การย้ายข้อมูลในอนาคตไปยังเวอร์ชันใหม่ๆ ง่ายขึ้น การกำหนดเวอร์ชันจะมีผลกับURL คำขอของคุณ กลยุทธ์นี้คล้ายกับประสบการณ์การใช้งาน Google Ads API

คำขอที่แข็งแกร่งยิ่งขึ้น

คำขอ URL ของ Merchant API ต้องมีพารามิเตอร์เพิ่มเติมเพื่อเรียกใช้ Merchant API ซึ่งรวมถึงทรัพยากร เวอร์ชัน ชื่อ (ตัวระบุ) และเมธอด (เมธอดที่ไม่เป็นไปตามมาตรฐาน) ดูข้อมูลเพิ่มเติมได้ที่ตัวระบุบัญชีและผลิตภัณฑ์และตัวอย่าง

หลักการ AIP สำหรับตัวระบุ

แม้ว่า Content API for Shopping จะใช้รหัสเพื่อระบุทรัพยากร (เช่น merchantId, productId) แต่ Merchant API จะใช้ตัวระบุ name เพื่อให้สอดคล้องกับ AIP (ดู หลักการปรับปรุง API)

ตัวระบุ {name} ประกอบด้วยตัวระบุทรัพยากรและทรัพยากรหลัก (หรืออาจมีหลายรายการ) เพื่อให้ {name} เท่ากับ accounts/{account}/products/{product}

การเรียกอ่านและเขียนทั้งหมดจะแสดงฟิลด์ name เป็นตัวระบุทรัพยากร

{name} ยังรวมถึงตัวระบุคอลเล็กชัน accounts/ และ products/ ด้วย

Merchant API ใช้ {account} เพื่ออ้างอิงถึงรหัส Merchant Center และ {product} เพื่ออ้างอิงถึงตัวระบุผลิตภัณฑ์

เช่น ใช้เมธอด getName() เพื่อดึง name จากทรัพยากร และจัดเก็บเอาต์พุตเป็นตัวแปรแทนการสร้าง 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}

ดูรายละเอียดเพิ่มเติมได้ที่การเปลี่ยนแปลง ตัวระบุ

อีกตัวอย่างหนึ่ง การดึงข้อมูลผลิตภัณฑ์ที่มีตัวระบุ en~US~1234 จาก รหัส Merchant Center 4321 โดยใช้ Merchant API จะมีลักษณะดังนี้

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/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

channel:contentLanguage:feedLabel:offerId

ใน Merchant API จะกลายเป็นดังนี้

contentLanguage~feedLabel~offerId

ฟิลด์หลักสำหรับทรัพยากรย่อย

ใน Merchant API แหล่งข้อมูลย่อยทั้งหมดมีฟิลด์ parent คุณสามารถใช้ฟิลด์ parent เพื่อระบุ {name} ของทรัพยากรที่จะ แทรกรายการย่อยแทนการส่งทรัพยากรหลักทั้งหมด คุณยังใช้ฟิลด์ parent กับ list ได้ด้วย

เช่น หากต้องการแสดงสินค้าคงคลังในร้านสำหรับผลิตภัณฑ์หนึ่งๆ ให้ระบุ name ของผลิตภัณฑ์ในฟิลด์ parent สำหรับเมธอด list ในกรณีนี้ productที่ระบุคือ parent ของ LocalInventory ที่ส่งคืน

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

หากต้องการดึงข้อมูลสินค้าคงคลังในร้านทั้งหมดสำหรับผลิตภัณฑ์ en~US~1234 และบัญชี 4321 คำขอจะมีลักษณะดังนี้

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

ผู้ปกครองคือ accounts/{account}/products/{product} โปรดทราบว่าในกรณีนี้ ทรัพยากร localInventories มี 2 รายการที่รวมอยู่ในตัวระบุชื่อ (accounts/ และ products/) เนื่องจากบัญชีเป็นทรัพยากรหลักของผลิตภัณฑ์

Enums ทั่วไป

การใช้ Enum ทั่วไปจะช่วยให้มีความสอดคล้องกันมากขึ้น

ฟิลด์ Destination.DestinationEnum จะระบุแพลตฟอร์มที่จะแสดงทรัพยากร DestinationEnum แสดงค่าทั้งหมดที่ใช้ได้สำหรับการกำหนดเป้าหมายปลายทางและ รวมไว้ใน API ย่อย เช่น แอตทริบิวต์โปรโมชัน

ฟิลด์ ReportingContext.ReportingContextEnum แสดงถึงบริบทที่ปัญหาเกี่ยวกับบัญชีและปัญหาเกี่ยวกับสินค้าของคุณมีผล ฟิลด์นี้ใช้ในวิธีการรายงานต่างๆ (เช่น สำหรับ IssueSeverityPerReportingContext)

ความเข้ากันได้แบบย้อนหลัง

เมื่อเริ่มใช้ Merchant API การผสานรวม Content API for Shopping ที่มีอยู่จะยังคงทำงานต่อไปโดยไม่หยุดชะงัก ดูข้อมูลเพิ่มเติมได้ที่ความเข้ากันได้

เมื่อย้ายข้อมูล API ย่อยไปยัง Merchant API แล้ว เราขอแนะนำให้คุณใช้เฉพาะ Merchant API สำหรับ API ย่อยที่ย้ายข้อมูล

ความพร้อมใช้งานของการเรียกกระบวนการระยะไกล (gRPC)

gRPC เป็นวิธีใหม่ที่แนะนำในการผสานรวมกับ Merchant API

ข้อดีมีดังนี้

การจัดกลุ่มที่กำหนดเองจะกลายเป็นการจัดกลุ่มในตัว

การประมวลผลแบบกลุ่มจะมีประสิทธิภาพมากขึ้นเมื่อคุณใช้การเรียกแบบไม่พร้อมกัน ดูข้อมูลเพิ่มเติม เกี่ยวกับการใช้การเรียกแบบขนานเพื่อให้ได้การประมวลผลแบบเป็นกลุ่มใน Merchant API และวิธีปรับโครงสร้างโค้ดสําหรับคําขอพร้อมกัน

เราขอแนะนำให้ใช้ไลบรารีไคลเอ็นต์เพื่อช่วยเร่งการย้ายข้อมูล

Merchant API ไม่รองรับเมธอด customBatch ที่แสดงใน Content API for Shopping แต่ให้ดูส่งคำขอหลายรายการพร้อมกันหรือเรียกใช้การเรียกแบบอะซิงโครนัสแทน

ตัวอย่าง 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.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);
  }
}

หากคุณใช้ customBatch ใน Content API และต้องการฟีเจอร์นี้สำหรับ Merchant API โปรดแจ้งให้เราทราบเหตุผลในความคิดเห็น

ฟีเจอร์สุดพิเศษ

ฟีเจอร์ในอนาคตจะปรากฏใน Merchant API เท่านั้น (จะมีข้อยกเว้นบางประการ เช่น ข้อกำหนดฟีดประจำปี 2025)

ฟีเจอร์พิเศษสำหรับ Merchant API มีดังนี้

  • Reviews API ใช้รีวิวเพื่อติดตั้งใช้งานและจัดการการให้คะแนนผลิตภัณฑ์และร้านค้า ดูข้อมูลเพิ่มเติมได้ที่รีวิวผู้ขายและรีวิวผลิตภัณฑ์
  • การแจ้งเตือน: ลงชื่อสมัครรับ การแจ้งเตือนแบบพุชสำหรับการเปลี่ยนแปลงข้อมูลบัญชีและข้อมูลสินค้า

ราคา

สิ่งที่เปลี่ยนแปลงสำหรับ Price ในแพ็กเกจ Merchant Common มีดังนี้

Content API for Shopping Merchant API
ฟิลด์จำนวนเงิน value:string amountMicros:int64
ฟิลด์สกุลเงิน currency:string currencyCode:string

ตอนนี้ระบบจะบันทึกจำนวน Price เป็นหน่วยไมโคร โดย 1 ล้านไมโครจะ เทียบเท่ากับหน่วยมาตรฐานของสกุลเงิน

ใน Content API for Shopping Price เป็นเลขทศนิยมในรูปแบบของสตริง

เปลี่ยนชื่อฟิลด์จำนวนเงินจาก value เป็น amountMicros แล้ว

เปลี่ยนชื่อฟิลด์สกุลเงินจาก currency เป็น currencyCode แล้ว รูปแบบยังคงเป็น ISO 4217

ข้อมูลอัปเดตและประกาศล่าสุด

ดูข้อมูลอัปเดตแบบละเอียดยิ่งขึ้นได้ในบันทึกประจำรุ่นของ API ย่อยแต่ละรายการ โปรดดูข้อมูลอัปเดตล่าสุดเพื่อดูข้อมูลอัปเดต Merchant API แบบรวมที่อัปเดตเป็นประจำ

ดูรายละเอียดเพิ่มเติมและเรียนรู้เพิ่มเติมเกี่ยวกับ Merchant API ได้ที่ภาพรวมในเว็บไซต์นักพัฒนาซอฟต์แวร์และคู่มือการย้ายข้อมูลโดยรวม

ดูรายละเอียดเกี่ยวกับ Merchant API และAPI ย่อยของ Merchant API ได้ที่การออกแบบ Merchant API