אפשר להשתמש במדריך הזה כדי להעביר את ההטמעה הקיימת של 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.
שיפורים ביחס ל-Content API
Merchant API מאפשר להפוך תהליכי עבודה ב-Merchant Center לאוטומטיים ולייעל אותם, ומציע יכולות משופרות בהשוואה ל-Content API.
תרחישים לדוגמה:
- ניהול חשבון אוטומטי
- ניהול מוצרים אוטומטי
- ניהול אוטומטי של מלאי שטחי הפרסום
- דוחות בהתאמה אישית
תחומי השיפור העיקריים:
- ממשקי API משניים עם פיצ'רים חדשים לשילוב הייחודי שלכם
- שיטות חדשות למלאי, לנתוני מוצרים ולממשקי API אחרים
- היכולת ליצור לא רק מקורות נתונים ראשיים, אלא כמה מקורות נתונים, כמו:
- העלאת ביקורות על מוצרים וביקורות על מוכרים
- באמצעות Merchant API, אפשר להפעיל התראות על שינויים בנתוני החשבון
תמיכה ב-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 בגרסה 2.1.
לדוגמה, אפשר להשתמש ב-Merchant Inventories API לצד ההטמעה הקיימת של Content API for Shopping בגרסה 2.1 products
. תוכלו להשתמש ב-Content API for Shopping כדי להעלות מוצר מקומי חדש (שמוכרים בחנות מקומית), ואז להשתמש במשאב Merchant Inventories API LocalInventory
כדי לנהל את המידע בחנות הפיזית לגבי המוצר הזה.
בקשות באצווה
ה-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.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);
}
}
אם אתם משתמשים ב-customBatch
ב-Content API ואתם צריכים את התכונה הזו ב-Merchant API, תוכלו לשלוח לנו משוב עם הסיבה לכך.
מזהים
כדי להתאים את עצמנו לעקרונות השיפור של Google API, ביצענו כמה שינויים במזהים של משאבי Merchant API.
השימוש ב-IDENTIFIER
מציין ששדה בתוך הודעת המשאב משמש לזיהוי המשאב. הוא מצורף לשדה השם. אפשר לעיין במאמר שדות שמייצגים שמות של משאבים.
הערך IDENTIFIER
מציין שהשדה לא מתקבל כקלט (כלומר OUTPUT_ONLY
) בהקשר של שיטת create, אבל הוא נחשב גם כ-IMMUTABLE
ומתקבל כקלט בשיטות של מוטציה שמקבלות את המשאב כקלט הראשי. דוגמה: Standard Update.
השם מחליף את המזהה
כל המשאבים של Merchant API משתמשים בשדה name
בתור המזהה הייחודי שלהם.
דוגמה לשימוש בשדה name
בשיחות:
GET https://merchantapi.googleapis.com/products/v1beta/accounts/4321/products/online~en~US~1234
כאשר name
שווה ל-accounts/4321/products/online~en~US~1234
.
השדה החדש name
מוחזר כמזהה המשאב לכל הקריאות לקריאה ולכתיבה ב-Merchant API.
לדוגמה, אפשר להטמיע שיטה getName()
כדי לאחזר את name
מהמשאב, ולאחסן את הפלט כמשתנה במקום ליצור את name
בעצמכם ממזהי העסק והמשאב.
תווים מפרידים
ב-Merchant API נעשה שימוש בקו מפריד במקום בפסיק כמפריד.
בטבלה הבאה מוצגת השוואה בין מזהה המוצר ב-Content API לבין מזהה המוצר ב-Merchant API:
Content API | Merchant API |
---|---|
channel:contentLanguage:feedLabel:offerId . לדוגמה, online:en:US:sku123 |
channel~contentLanguage~feedLabel~offerId . לדוגמה, online~en~US~sku123 |
שדות הורה למשאבים צאצאים
ב-Merchant API, לכל משאבי הצאצאים יש את השדה parent
. אפשר להשתמש בשדה parent
כדי לציין את name
של המשאב שאליו רוצים להוסיף את הצאצא, במקום להעביר את משאב ההורה כולו.
אפשר גם להשתמש בשדה parent
עם השיטות list
כדי לרשום את משאבי הצאצאים של parent
הזה.
לדוגמה, כדי לקבל רשימה של מלאי בחנויות מקומיות של מוצר מסוים, צריך לציין את name
של המוצר בשדה parent
של השיטה list
. במקרה כזה, הערך של product
הוא הערך של parent
של המשאבים LocalInventory
שהוחזרו.
GET https://merchantapi.googleapis.com/inventories/v1beta/{parent}/localInventories
כדי לאחזר את כל המלאי המקומי של המוצר online~en~US~1234
והחשבון 4321
, הבקשה תיראה כך:
GET https://merchantapi.googleapis.com/inventories/v1beta/accounts/4321/products/online~en~US~1234/localInventories
כאשר parent שווה ל-accounts/{account}/products/{product}. לתשומת ליבכם: במקרה הזה, למזהה השם של localInventories יש שני הורים (accounts/ ו-products/), כי החשבון הוא ההורה של משאב המוצר.
סוגים נפוצים
ריכזנו כאן כמה סוגים נפוצים ששותפו בין ממשקי ה-API המשניים של Merchant API.
Destination.DestinationEnum
אפשר להשתמש בשדה Destination.DestinationEnum כדי לקבוע באילו פלטפורמות המשאבים יוצגו. בשדה DestinationEnum
מפורטים כל הערכים הזמינים לטירגוט לפי יעד. ממשקי ה-API מאחדים את DestinationEnum
במספר ממשקי API משניים, למשל למאפייני מבצעים.
ReportingContext.ReportingContextEnum
השדה ReportingContext.ReportingContextEnum מייצג את ההקשר שאליו רלוונטיות הבעיות בחשבון ובמוצרים. השדה הזה משמש בשיטות דיווח שונות (למשל, IssueSeverityPerReportingContext).
מחיר
אלה השינויים ב-Price
בחבילה Merchant Common:
Content API | Merchant API | |
---|---|---|
שדה הסכום | value:string |
amountMicros:int64 |
שדה המטבע | currency:string
|
currencyCode:string |
הסכום של Price
מתועד עכשיו במיקרו-יחידות, כאשר מיליון מיקרו-יחידות שווה ליחידה הסטנדרטית של המטבע שלכם.
ב-Content API for Shopping, הערך של Price
היה מספר עשרוני בצורת מחרוזת.
שם השדה amount השתנה מ-value
ל-amountMicros
שם השדה של המטבע השתנה מ-currency
ל-currencyCode
. הפורמט נשאר ISO 4217.