این سند برخیاز تکنیکهایی را که میتوانید برای بهبود عملکرد برنامهتان استفاده کنید پوشش میدهد. در برخی موارد، از نمونههای میاناهای برنامهسازی کاربردی دیگر یا میاناهای برنامهسازی کاربردی عمومی برای توضیح ایدههای ارائهشده استفاده میشود. بااینحال، همین مفاهیم برای Google Wallet API نیز قابلاجرا است.
فشردهسازی بااستفاده از gzip
یک راه آسان و راحت برای کاهش پهنای باند مورد نیاز برای هر درخواست، فعال کردن فشردهسازی gzip است. اگرچه این کار به زمان واحد پردازش مرکزی بیشتری برای ازحالت فشرده خارج کردن نتایج نیاز دارد، اما موازنه با هزینههای شبکه معمولاً آن را بسیار ارزشمند میکند.
برای دریافت پاسخ کدبندیشده با gzip، باید دو کار انجام دهید: سرصفحه Accept-Encoding را تنظیم کنید و عامل کاربر خود را بهگونهای تغییر دهید که رشته gzip را دربرگیرد. در اینجا نمونهای از سرصفحههای HTTP با قالببندی مناسب برای فعال کردن فشردهسازی gzip آورده شده است:
Accept-Encoding: gzip User-Agent: my program (gzip)
کار کردن با منابع جزئی
راه دیگر برای بهبود عملکرد فراخوانیهای API شما، ارسال و دریافت تنها بخشی از دادههایی است که به آن علاقه دارید. این کار به برنامه شما اجازه میدهد از انتقال، تجزیه، و ذخیره فیلدهای غیرضروری اجتناب کند، بنابراین میتواند از منابعی مانند شبکه، CPU، و حافظه بهطور کارآمدتری استفاده کند.
دو نوع درخواست جزئی وجود دارد:
- پاسخ جزئی: درخواستی که در آن مشخص میکنید کدام فیلدها در پاسخ گنجانده شود (از پارامتر درخواست
fieldsاستفاده کنید). - وصله: درخواست بهروزرسانی که در آن فقط فیلدهایی را که میخواهید تغییر دهید ارسال میکنید (از فعل HTTP
PATCHاستفاده کنید).
جزئیات بیشتر درباره ارسال درخواستهای جزئی در بخشهای زیر ارائه شده است.
پاسخ جزئی
بهطور پیشفرض، سرور پساز پردازش درخواستها، نمایش کامل منبع را برمیگرداند. برای عملکرد بهتر، میتوانید از سرور بخواهید فقط فیلدهایی را که واقعاً نیاز دارید ارسال کند و درعوض پاسخ جزئی دریافت کنید.
برای درخواست پاسخ جزئی، از پارامتر درخواست fields برای مشخص کردن فیلدهایی که میخواهید برگردانده شوند استفاده کنید. میتوانید از این پارامتر با هر درخواستی که دادههای پاسخ را برمیگرداند استفاده کنید.
توجه داشته باشید که پارامتر fields فقط بر دادههای پاسخ تأثیر میگذارد؛ بر دادههایی که باید ارسال کنید (درصورت وجود) تأثیری ندارد. برای کاهش مقدار دادهای که هنگام اصلاح منابع ارسال میکنید، از درخواست وصله استفاده کنید.
مثال
مثال زیر استفاده از پارامتر fields را با یک API عمومی (خیالی) «نسخه نمایشی» نشان میدهد.
درخواست ساده: این درخواست HTTP GET پارامتر fields را حذف میکند و منبع کامل را برمیگرداند.
https://www.googleapis.com/demo/v1
پاسخ کامل منبع: دادههای کامل منبع شامل فیلدهای زیر است، بههمراه بسیاری موارد دیگر که برای اختصار حذف شدهاند.
{
"kind": "demo",
...
"items": [
{
"title": "First title",
"comment": "First comment.",
"characteristics": {
"length": "short",
"accuracy": "high",
"followers": ["Jo", "Will"],
},
"status": "active",
...
},
{
"title": "Second title",
"comment": "Second comment.",
"characteristics": {
"length": "long",
"accuracy": "medium"
"followers": [ ],
},
"status": "pending",
...
},
...
]
}درخواست برای پاسخ جزئی: درخواست زیر برای همین منبع از پارامتر fields برای کاهش قابلتوجه مقدار دادههای برگرداندهشده استفاده میکند.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
پاسخ جزئی: در پاسخ به درخواست بالا، سرور پاسخی را ارسال میکند که فقط حاوی اطلاعات نوع بههمراه آرایه موارد کاهشیافته است که فقط شامل عنوان HTML و اطلاعات مشخصه طول در هر مورد است.
200 OK
{
"kind": "demo",
"items": [{
"title": "First title",
"characteristics": {
"length": "short"
}
}, {
"title": "Second title",
"characteristics": {
"length": "long"
}
},
...
]
}توجه داشته باشید که پاسخ یک شیء JSON است که فقط شامل فیلدهای انتخابشده و اشیاء والد دربرگیرنده آنها است.
جزئیات مربوط به نحوه قالببندی پارامتر fields در ادامه پوشش داده شده است و پساز آن جزئیات بیشتری درباره آنچه دقیقاً در پاسخ برگردانده میشود ارائه شده است.
خلاصه نحو پارامتر فیلدها
قالب مقدار پارامتر درخواست fields براساس دستورگان XPath است. نحو پشتیبانیشده در زیر خلاصه شده است و نمونههای اضافی در بخش زیر ارائه شده است.
- برای انتخاب چند فیلد، از فهرست جداشده با کاما استفاده کنید.
- از
a/bبرای انتخاب فیلدbکه در فیلدaتودرتو است استفاده کنید؛ ازa/b/cبرای انتخاب فیلدcکه درbتودرتو است استفاده کنید.
استثنا: برای پاسخهای میانای برنامهسازی کاربردی که از پوشانندههای «داده» استفاده میکنند، جایی که پاسخ در شیء
dataکه شبیهdata: { ... }است تودرتو شده است، «data» را در مشخصاتfieldsلحاظ نکنید. افزودن هدف اصلی داده با مشخصات فیلد مثلdata/a/bباعث بروز خطا میشود. درعوض، فقط از مشخصاتfieldsمثلa/bاستفاده کنید. - با قرار دادن عبارتها در پرانتز «
( )»، از یک گزینشگر فرعی برای درخواست مجموعهای از زیرفیلدهای خاص آرایهها یا اشیا استفاده کنید.برای مثال:
fields=items(id,author/email)فقط شناسه کالا و ایمیل نویسنده را برای هر عنصر در آرایه کالاها برمیگرداند. همچنین میتوانید یک زیرفیلد تکی را مشخص کنید، که در آنfields=items(id)معادلfields=items/idاست. - درصورت نیاز، از نویسههای عام در انتخاب فیلدها استفاده کنید.
برای مثال:
fields=items/pagemap/*همه عناصر در یک صفحهنقشه را انتخاب میکند.
نمونههای بیشتر از استفاده از پارامتر فیلدها
نمونههای زیر شامل توضیحاتی درباره نحوه تأثیرگذاری مقدار پارامتر fields بر پاسخ است.
توجه: مانند همه مقادیر پارامتر پُرسمان، مقدار پارامتر fields باید کدگذاری نشانی وب باشد. برای خوانایی بهتر، مثالهای این سند کدبندی را حذف میکنند.
- فیلدهایی را که میخواهید برگردانده شوند شناسایی کنید، یا انتخابهای فیلد را انجام دهید.
- مقدار پارامتر درخواست
fieldsفهرستی از فیلدها است که با کاما از هم جدا شدهاند و هر فیلد نسبت به ریشه پاسخ مشخص میشود. بنابراین، اگر عملیات فهرست را انجام دهید، پاسخ یک مجموعه است و معمولاً شامل آرایهای از منابع میشود. اگر عملیاتی را انجام میدهید که یک منبع واحد را برمیگرداند، فیلدها نسبت به آن منبع مشخص میشوند. اگر فیلدی که انتخاب میکنید آرایه باشد (یا بخشی از آرایه باشد)، سرور بخش انتخابی همه عناصر آرایه را برمیگرداند.
در اینجا چند نمونه سطح مجموعه آورده شده است:
مثالها جلوه itemsهمه عناصر موجود در آرایه موارد، ازجمله همه فیلدهای موجود در هر عنصر، اما هیچ فیلد دیگری را برمیگرداند. etag,itemsهم فیلد etagو هم همه عناصر موجود در آرایه موارد را برمیگرداند.items/titleفقط فیلد titleرا برای همه عناصر در آرایه موارد برمیگرداند.
هرگاه فیلد تودرتویی برگردانده شود، پاسخ شامل اشیای والد دربرگیرنده میشود. فیلدهای والد هیچ فیلد فرزند دیگری را دربرنمیگیرد، مگراینکه آنها نیز بهطور صریح انتخاب شده باشند.context/facets/labelفقط فیلد labelرا برای همه اعضای آرایهfacetsبرمیگرداند که خودش در زیر شیءcontextقرار دارد.items/pagemap/*/titleبرای هر عنصر در آرایه موارد، فقط فیلد title(درصورت وجود) همه اشیایی را که فرزندpagemapهستند برمیگرداند.
در اینجا چند مثال در سطح منبع آورده شده است:
مثالها جلوه titleفیلد titleمنبع درخواستشده را برمیگرداند.author/uriزیرفیلد uriاز شیءauthorرا در منبع درخواستشده برمیگرداند.links/*/hrefفیلد hrefهمه اشیایی را که فرزندlinksهستند برمیگرداند. - فقط بخشهایی از فیلدهای خاص را بااستفاده از زیرانتخابها درخواست کنید.
- بهطور پیشفرض، اگر درخواست شما فیلدهای خاصی را مشخص کند، سرور اشیاء یا عناصر آرایه را بهطور کامل برمیگرداند. میتوانید پاسخی را مشخص کنید که فقط شامل زیرفیلدهای خاصی باشد. این کار را بااستفاده از نحو زیرانتخاب «
( )» انجام میدهید، مانند مثال زیر.مثال جلوه items(title,author/uri)فقط مقادیر titleوuriنویسنده را برای هر عنصر در آرایه موارد برمیگرداند.
رسیدگی به پاسخهای ناقص
پساز اینکه سرور درخواست معتبری را که شامل پارامتر پُرسمان fields است پردازش کرد، رمز وضعیت اچتیتیپیاس 200 OK را بههمراه دادههای درخواستشده برمیگرداند. اگر پارامتر پُرسمان fields خطا داشته باشد یا بههر دلیلی نامعتبر باشد، سرور کد وضعیت HTTP 400 Bad Request را بههمراه پیام خطایی که به کاربر میگوید انتخاب فیلد او چه مشکلی داشته است (برای نمونه، "Invalid field selection a/b") برمیگرداند.
در اینجا نمونهای از پاسخ جزئی که در بخش مقدماتی بالا نشان داده شده است آورده شده است. درخواست از پارامتر fields برای مشخص کردن فیلدهای برگشتی استفاده میکند.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
پاسخ ناتمام به این شکل است:
200 OK
{
"kind": "demo",
"items": [{
"title": "First title",
"characteristics": {
"length": "short"
}
}, {
"title": "Second title",
"characteristics": {
"length": "long"
}
},
...
]
}توجه: برای میاناهای برنامهسازی کاربردی که از پارامترهای پُرسمان برای صفحهبندی دادهها پشتیبانی میکنند (برای مثال، maxResults و nextPageToken)، از این پارامترها برای کاهش نتایج هر پُرسمان به اندازه قابلمدیریت استفاده کنید. درغیراینصورت، ممکن است بهبود عملکردی که با پاسخ جزئی امکانپذیر است محقق نشود.
وصله (بهروزرسانی جزئی)
همچنین میتوانید هنگام اصلاح منابع، از ارسال دادههای غیرضروری خودداری کنید. برای ارسال دادههای بهروزشده فقط برای فیلدهای خاصی که تغییر میدهید، از فعل HTTP PATCH استفاده کنید. معناشناسی وصله شرحدادهشده در این سند با معناشناسی وصله در پیادهسازی قدیمیتر GData برای بهروزرسانی جزئی متفاوت (و سادهتر) است.
مثال کوتاه زیر نشان میدهد که چگونه استفاده از patch دادههایی را که باید برای انجام بهروزرسانی کوچک ارسال کنید بهحداقل میرساند.
مثال
این مثال یک درخواست وصله ساده را نشان میدهد که فقط عنوان منبع API عمومی (خیالی) «نسخه نمایشی» را بهروز میکند. منبع همچنین دارای یک نظر، مجموعهای از ویژگیها، وضعیت و بسیاری از فیلدهای دیگر است، اما این درخواست فقط فیلد title را ارسال میکند، زیرا این تنها فیلدی است که اصلاح میشود:
PATCH https://www.googleapis.com/demo/v1/324
Authorization: Bearer your_auth_token
Content-Type: application/json
{
"title": "New title"
}پاسخ:
200 OK
{
"title": "New title",
"comment": "First comment.",
"characteristics": {
"length": "short",
"accuracy": "high",
"followers": ["Jo", "Will"],
},
"status": "active",
...
}سرور رمز وضعیت 200 OK را بههمراه نمایش کامل منبع بهروزشده برمیگرداند. ازآنجاییکه فقط فیلد title در درخواست وصله گنجانده شده بود، این تنها مقداری است که با مقدار قبلی متفاوت است.
توجه: اگر از پارامتر fields پاسخ جزئی در ترکیب با وصله استفاده کنید، میتوانید کارایی درخواستهای بهروزرسانی خود را حتی بیشتر افزایش دهید. درخواست وصله فقط اندازه درخواست را کاهش میدهد. پاسخ جزئی اندازه پاسخ را کاهش میدهد. بنابراین برای کاهش مقدار دادههای ارسالشده در هر دو جهت، از درخواست وصله با پارامتر fields استفاده کنید.
معناشناسی درخواست وصله
بدنه درخواست وصله فقط شامل فیلدهای منبعی است که میخواهید اصلاح کنید. وقتی فیلدی را مشخص میکنید، باید هر شیء والد دربرگیرندهای را اضافه کنید، درست همانطور که والدین دربرگیرنده با پاسخ جزئی برگردانده میشوند. دادههای اصلاحشدهای که ارسال میکنید با دادههای شیء والد (درصورت وجود) ادغام میشود.
- افزودن: برای افزودن فیلدی که ازقبل وجود ندارد، فیلد جدید و مقدار آن را مشخص کنید.
- اصلاح: برای تغییر دادن مقدار فیلد موجود، فیلد را مشخص کنید و آن را روی مقدار جدید تنظیم کنید.
- حذف: برای حذف فیلد، فیلد را مشخص کنید و آن را روی
nullتنظیم کنید. برای مثال،"comment": null. همچنین میتوانید با تنظیم کردن شیء رویnull، کل آن را (اگر قابلتغییر باشد) حذف کنید. اگر از کتابخانه کارخواه Java API استفاده میکنید، بهجای آن ازData.NULL_STRINGاستفاده کنید؛ برای جزئیات، JSON null را ببینید.
نکته درباره آرایهها: درخواستهای وصلهای که حاوی آرایه هستند، آرایه موجود را با آرایهای که شما ارائه میدهید جایگزین میکنند. نمیتوانید موارد را در آرایه بهصورت تکهتکه اصلاح، اضافه، یا حذف کنید.
استفاده از وصله در چرخه خواندن-اصلاح-نوشتن
یک روش مفید میتواند این باشد که ابتدا پاسخ جزئی را با دادههایی که میخواهید اصلاح کنید بازیابی کنید. این امر بهویژه برای منابعی که از ETags استفاده میکنند مهم است، زیرا برای بهروزرسانی موفقیتآمیز منبع باید مقدار ETag فعلی را در سرصفحه If-Match HTTP ارائه دهید. پساز دریافت دادهها، میتوانید مقادیر موردنظرتان را تغییر دهید و نمایش جزئی اصلاحشده را با درخواست وصله برگردانید. در اینجا مثالی آورده شده است که فرض میکند منبع «نمایشی» از ETags استفاده میکند:
GET https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token
این پاسخ جزئی است:
200 OK
{
"etag": "ETagString"
"title": "New title"
"comment": "First comment.",
"characteristics": {
"length": "short",
"level": "5",
"followers": ["Jo", "Will"],
}
}درخواست وصله زیر براساس آن پاسخ است. همانطور که در زیر نشان داده شده است، از پارامتر fields نیز برای محدود کردن دادههای برگشتی در پاسخ وصله استفاده میکند:
PATCH https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token Content-Type: application/json If-Match: "ETagString"
{
"etag": "ETagString"
"title": "", /* Clear the value of the title by setting it to the empty string. */
"comment": null, /* Delete the comment by replacing its value with null. */
"characteristics": {
"length": "short",
"level": "10", /* Modify the level value. */
"followers": ["Jo", "Liz"], /* Replace the followers array to delete Will and add Liz. */
"accuracy": "high" /* Add a new characteristic. */
},
}سرور با رمز وضعیت HTTP 200 OK و نمایش جزئی منبع بهروزشده پاسخ میدهد:
200 OK
{
"etag": "newETagString"
"title": "", /* Title is cleared; deleted comment field is missing. */
"characteristics": {
"length": "short",
"level": "10", /* Value is updated.*/
"followers": ["Jo" g>"Liz"], /* New follower Liz is present; deleted Will is missing. */
"accuracy": "high" /* New characteristic is present. */
}
} ساختن درخواست وصله بهطور مستقیم
برای برخیاز درخواستهای وصله، باید آنها را براساس دادههایی که قبلاً بازیابی کردهاید ایجاد کنید. برای مثال، اگر میخواهید موردی را به آرایه اضافه کنید و نمیخواهید هیچکدام از عناصر آرایه موجود را ازدست بدهید، ابتدا باید دادههای موجود را دریافت کنید. بههمین ترتیب، اگر یک API از ETags استفاده میکند، باید مقدار ETag قبلی را همراه با درخواست خود ارسال کنید تا منبع با موفقیت بهروز شود.
توجه: میتوانید از "If-Match: *" سرصفحه HTTP استفاده کنید تا وقتی از ETags استفاده میشود، وصله را بهاجبار اعمال کنید. اگر این کار را انجام دهید، نیازی نیست که قبلاز نوشتن، بخوانید.
اما برای موقعیتهای دیگر، میتوانید درخواست وصله را مستقیماً بدون بازیابی دادههای موجود بسازید. برای مثال، بهراحتی میتوانید درخواست وصلهای راهاندازی کنید که فیلدی را به مقدار جدیدی بهروزرسانی میکند یا فیلد جدیدی اضافه میکند. بهعنوان مثال:
PATCH https://www.googleapis.com/demo/v1/324?fields=comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json
{
"comment": "A new comment",
"characteristics": {
"volume": "loud",
"accuracy": null
}
}با این درخواست، اگر فیلد نظر مقدار موجودی داشته باشد، مقدار جدید آن را ملغی میکند؛ درغیراینصورت، مقدار جدید تنظیم میشود. بهطور مشابه، اگر ویژگی حجم وجود داشته باشد، مقدار آن رونویسی میشود؛ اگر وجود نداشته باشد، ایجاد میشود. فیلد دقت، درصورت تنظیم شدن، برداشته میشود.
مدیریت پاسخ به وصله
پساز پردازش درخواست وصله معتبر، API کد پاسخ HTTP 200 OK را بههمراه نمایش کامل منبع اصلاحشده برمیگرداند. اگر API از ETag استفاده کند، سرور مقادیر ETag را هنگام پردازش موفقیتآمیز درخواست وصله بهروز میکند، درست همانطور که با PUT انجام میدهد.
درخواست وصله کل نمایش منبع را برمیگرداند، مگر اینکه از پارامتر fields برای کاهش مقدار دادهای که برمیگرداند استفاده کنید.
اگر درخواست وصله منجر به وضعیت منبع جدیدی شود که ازنظر نحوی یا معنایی نامعتبر است، سرور رمز وضعیت HTTP 400 Bad Request یا 422 Unprocessable Entity را برمیگرداند و وضعیت منبع بدون تغییر باقی میماند. برای مثال، اگر تلاش کنید مقدار فیلد الزامی را حذف کنید، سرور خطا برمیگرداند.
نشانهگذاری جایگزین وقتی فعل HTTP از نوع PATCH پشتیبانی نمیشود
اگر دیوار آتش شما درخواستهای HTTP PATCH را مجاز نمیداند، درخواست HTTP POST را انجام دهید و سرصفحه ملغیکننده را روی PATCH تنظیم کنید، همانطور که در زیر نشان داده شده است:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
تفاوت بین وصله و بهروزرسانی
در عمل، وقتی دادهها را برای درخواست بهروزرسانی که از فعل HTTP PUT استفاده میکند ارسال میکنید، فقط باید فیلدهایی را ارسال کنید که الزامی یا اختیاری هستند؛ اگر مقادیری را برای فیلدهایی که توسط سرور تنظیم شدهاند ارسال کنید، نادیده گرفته میشوند. اگرچه ممکن است این روش راه دیگری برای انجام بهروزرسانی جزئی بهنظر برسد، اما این رویکرد محدودیتهایی دارد. با بهروزرسانیهایی که از فعل HTTP PUT استفاده میکنند، اگر پارامترهای الزامی را ارائه نکنید درخواست ناموفق خواهد بود و اگر پارامترهای اختیاری را ارائه نکنید دادههای قبلاً تنظیمشده پاک خواهد شد.
به همین دلیل استفاده از وصله بسیار ایمنتر است. فقط برای فیلدهایی که میخواهید تغییر دهید داده ارائه میکنید؛ فیلدهایی که حذف میکنید پاک نمیشوند. تنها استثنای این قانون درمورد عناصر یا آرایههای تکراری رخ میدهد: اگر همه آنها را حذف کنید، همانطور که هستند باقی میمانند؛ اگر هرکدام از آنها را ارائه دهید، کل مجموعه با مجموعهای که ارائه میدهید جایگزین میشود.
درخواستهای دستهای به «کیف پول Google»
Google Wallet API از دستهبندی فراخوانیهای میانای برنامهسازی کاربردی باهم پشتیبانی میکند تا تعداد اتصالاتی را که مشتری باید برقرار کند کاهش دهد. برای اطلاعات بیشتر درباره ساختار درخواست و پاسخ دستهای، به جزئیات دسته مراجعه کنید.
کد نمونه زیر درخواستهای دستهای را نشان میدهد. مثالهای Java و PHP از کتابخانههای «کیف پول Google» برای سادهسازی ایجاد کلاس و شیء استفاده میکنند.
جاوا
برای شروع یکپارچهسازی در Java، به نمونههای کد کامل ما در GitHub مراجعه کنید.
/** * Batch create Google Wallet objects from an existing class. * * @param issuerId The issuer ID being used for this request. * @param classSuffix Developer-defined unique ID for this pass class. */ public void batchCreateObjects(String issuerId, String classSuffix) throws IOException { // Create the batch request client BatchRequest batch = service.batch(new HttpCredentialsAdapter(credentials)); // The callback will be invoked for each request in the batch JsonBatchCallback<EventTicketObject> callback = new JsonBatchCallback<EventTicketObject>() { // Invoked if the request was successful public void onSuccess(EventTicketObject response, HttpHeaders responseHeaders) { System.out.println("Batch insert response"); System.out.println(response.toString()); } // Invoked if the request failed public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) { System.out.println("Error Message: " + e.getMessage()); } }; // Example: Generate three new pass objects for (int i = 0; i < 3; i++) { // Generate a random object suffix String objectSuffix = UUID.randomUUID().toString().replaceAll("[^\\w.-]", "_"); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject EventTicketObject batchObject = new EventTicketObject() .setId(String.format("%s.%s", issuerId, objectSuffix)) .setClassId(String.format("%s.%s", issuerId, classSuffix)) .setState("ACTIVE") .setHeroImage( new Image() .setSourceUri( new ImageUri() .setUri( "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Hero image description")))) .setTextModulesData( List.of( new TextModuleData() .setHeader("Text module header") .setBody("Text module body") .setId("TEXT_MODULE_ID"))) .setLinksModuleData( new LinksModuleData() .setUris( Arrays.asList( new Uri() .setUri("http://maps.google.com/") .setDescription("Link module URI description") .setId("LINK_MODULE_URI_ID"), new Uri() .setUri("tel:6505555555") .setDescription("Link module tel description") .setId("LINK_MODULE_TEL_ID")))) .setImageModulesData( List.of( new ImageModuleData() .setMainImage( new Image() .setSourceUri( new ImageUri() .setUri( "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Image module description")))) .setId("IMAGE_MODULE_ID"))) .setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value")) .setLocations( List.of( new LatLongPoint() .setLatitude(37.424015499999996) .setLongitude(-122.09259560000001))) .setSeatInfo( new EventSeat() .setSeat( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("42"))) .setRow( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("G3"))) .setSection( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("5"))) .setGate( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("A")))) .setTicketHolderName("Ticket holder name") .setTicketNumber("Ticket number"); service.eventticketobject().insert(batchObject).queue(batch, callback); } // Invoke the batch API calls batch.execute(); }
PHP
برای شروع ادغام در PHP، به نمونه کدهای کامل ما در GitHub مراجعه کنید.
/** * Batch create Google Wallet objects from an existing class. * * @param string $issuerId The issuer ID being used for this request. * @param string $classSuffix Developer-defined unique ID for the pass class. */ public function batchCreateObjects(string $issuerId, string $classSuffix) { // Update the client to enable batch requests $this->client->setUseBatch(true); $batch = $this->service->createBatch(); // Example: Generate three new pass objects for ($i = 0; $i < 3; $i++) { // Generate a random object suffix $objectSuffix = preg_replace('/[^\w.-]/i', '_', uniqid()); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject $batchObject = new EventTicketObject([ 'id' => "{$issuerId}.{$objectSuffix}", 'classId' => "{$issuerId}.{$classSuffix}", 'state' => 'ACTIVE', 'heroImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Hero image description' ]) ]) ]), 'textModulesData' => [ new TextModuleData([ 'header' => 'Text module header', 'body' => 'Text module body', 'id' => 'TEXT_MODULE_ID' ]) ], 'linksModuleData' => new LinksModuleData([ 'uris' => [ new Uri([ 'uri' => 'http://maps.google.com/', 'description' => 'Link module URI description', 'id' => 'LINK_MODULE_URI_ID' ]), new Uri([ 'uri' => 'tel:6505555555', 'description' => 'Link module tel description', 'id' => 'LINK_MODULE_TEL_ID' ]) ] ]), 'imageModulesData' => [ new ImageModuleData([ 'mainImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Image module description' ]) ]) ]), 'id' => 'IMAGE_MODULE_ID' ]) ], 'barcode' => new Barcode([ 'type' => 'QR_CODE', 'value' => 'QR code value' ]), 'locations' => [ new LatLongPoint([ 'latitude' => 37.424015499999996, 'longitude' => -122.09259560000001 ]) ], 'seatInfo' => new EventSeat([ 'seat' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => '42' ]) ]), 'row' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'G3' ]) ]), 'section' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => '5' ]) ]), 'gate' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'A' ]) ]) ]), 'ticketHolderName' => 'Ticket holder name', 'ticketNumber' => 'Ticket number' ]); $batch->add($this->service->eventticketobject->insert($batchObject)); } // Make the batch request $batchResponse = $batch->execute(); print "Batch insert response\n"; foreach ($batchResponse as $key => $value) { if ($value instanceof Google_Service_Exception) { print_r($value->getErrors()); continue; } print "{$value->getId()}\n"; } }
Python
برای شروع ادغام در Python، به نمونههای کد کامل ما در GitHub مراجعه کنید.
def batch_create_objects(self, issuer_id: str, class_suffix: str): """Batch create Google Wallet objects from an existing class. The request body will be a multiline string. See below for information. https://cloud.google.com/compute/docs/api/how-tos/batch#example Args: issuer_id (str): The issuer ID being used for this request. class_suffix (str): Developer-defined unique ID for this pass class. """ batch = self.client.new_batch_http_request() # Example: Generate three new pass objects for _ in range(3): # Generate a random object suffix object_suffix = str(uuid.uuid4()).replace('[^\\w.-]', '_') # See link below for more information on required properties # https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject batch_object = { 'id': f'{issuer_id}.{object_suffix}', 'classId': f'{issuer_id}.{class_suffix}', 'state': 'ACTIVE', 'heroImage': { 'sourceUri': { 'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Hero image description' } } }, 'textModulesData': [{ 'header': 'Text module header', 'body': 'Text module body', 'id': 'TEXT_MODULE_ID' }], 'linksModuleData': { 'uris': [{ 'uri': 'http://maps.google.com/', 'description': 'Link module URI description', 'id': 'LINK_MODULE_URI_ID' }, { 'uri': 'tel:6505555555', 'description': 'Link module tel description', 'id': 'LINK_MODULE_TEL_ID' }] }, 'imageModulesData': [{ 'mainImage': { 'sourceUri': { 'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Image module description' } } }, 'id': 'IMAGE_MODULE_ID' }], 'barcode': { 'type': 'QR_CODE', 'value': 'QR code' }, 'locations': [{ 'latitude': 37.424015499999996, 'longitude': -122.09259560000001 }], 'seatInfo': { 'seat': { 'defaultValue': { 'language': 'en-US', 'value': '42' } }, 'row': { 'defaultValue': { 'language': 'en-US', 'value': 'G3' } }, 'section': { 'defaultValue': { 'language': 'en-US', 'value': '5' } }, 'gate': { 'defaultValue': { 'language': 'en-US', 'value': 'A' } } }, 'ticketHolderName': 'Ticket holder name', 'ticketNumber': 'Ticket number' } batch.add(self.client.eventticketobject().insert(body=batch_object)) # Invoke the batch API calls response = batch.execute() print('Batch complete')
C#
برای شروع ادغام در C#، به نمونههای کد ما در GitHub مراجعه کنید.
/// <summary> /// Batch create Google Wallet objects from an existing class. /// </summary> /// <param name="issuerId">The issuer ID being used for this request.</param> /// <param name="classSuffix">Developer-defined unique ID for this pass class.</param> public async void BatchCreateObjects(string issuerId, string classSuffix) { // The request body will be a multiline string // See below for more information // https://cloud.google.com/compute/docs/api/how-tos/batch//example string data = ""; HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Bearer", credentials.GetAccessTokenForRequestAsync().Result ); // Example: Generate three new pass objects for (int i = 0; i < 3; i++) { // Generate a random object suffix string objectSuffix = Regex.Replace(Guid.NewGuid().ToString(), "[^\\w.-]", "_"); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject EventTicketObject batchObject = new EventTicketObject { Id = $"{issuerId}.{objectSuffix}", ClassId = $"{issuerId}.{classSuffix}", State = "ACTIVE", HeroImage = new Image { SourceUri = new ImageUri { Uri = "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Hero image description" } } }, TextModulesData = new List<TextModuleData> { new TextModuleData { Header = "Text module header", Body = "Text module body", Id = "TEXT_MODULE_ID" } }, LinksModuleData = new LinksModuleData { Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri> { new Google.Apis.Walletobjects.v1.Data.Uri { UriValue = "http://maps.google.com/", Description = "Link module URI description", Id = "LINK_MODULE_URI_ID" }, new Google.Apis.Walletobjects.v1.Data.Uri { UriValue = "tel:6505555555", Description = "Link module tel description", Id = "LINK_MODULE_TEL_ID" } } }, ImageModulesData = new List<ImageModuleData> { new ImageModuleData { MainImage = new Image { SourceUri = new ImageUri { Uri = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Image module description" } } }, Id = "IMAGE_MODULE_ID" } }, Barcode = new Barcode { Type = "QR_CODE", Value = "QR code" }, Locations = new List<LatLongPoint> { new LatLongPoint { Latitude = 37.424015499999996, Longitude = -122.09259560000001 } }, SeatInfo = new EventSeat { Seat = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "42" } }, Row = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "G3" } }, Section = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "5" } }, Gate = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "A" } } }, TicketHolderName = "Ticket holder name", TicketNumber = "Ticket number" }; data += "--batch_createobjectbatch\n"; data += "Content-Type: application/json\n\n"; data += "POST /walletobjects/v1/eventTicketObject/\n\n"; data += JsonConvert.SerializeObject(batchObject) + "\n\n"; } data += "--batch_createobjectbatch--"; // Invoke the batch API calls HttpRequestMessage batchObjectRequest = new HttpRequestMessage( HttpMethod.Post, "https://walletobjects.googleapis.com/batch"); batchObjectRequest.Content = new StringContent(data); batchObjectRequest.Content.Headers.ContentType = new MediaTypeHeaderValue( "multipart/mixed"); // `boundary` is the delimiter between API calls in the batch request batchObjectRequest.Content.Headers.ContentType.Parameters.Add( new NameValueHeaderValue("boundary", "batch_createobjectbatch")); HttpResponseMessage batchObjectResponse = httpClient.Send( batchObjectRequest); string batchObjectContent = await batchObjectResponse .Content .ReadAsStringAsync(); Console.WriteLine("Batch insert response"); Console.WriteLine(batchObjectContent); }
Node.js
برای شروع ادغام در Node، به نمونههای کد کامل ما در GitHub مراجعه کنید.
/** * Batch create Google Wallet objects from an existing class. * * @param {string} issuerId The issuer ID being used for this request. * @param {string} classSuffix Developer-defined unique ID for this pass class. */ async batchCreateObjects(issuerId, classSuffix) { // See below for more information // https://cloud.google.com/compute/docs/api/how-tos/batch#example let data = ''; let batchObject; let objectSuffix; // Example: Generate three new pass objects for (let i = 0; i < 3; i++) { // Generate a random object suffix objectSuffix = uuidv4().replace('[^\w.-]', '_'); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject batchObject = { 'id': `${issuerId}.${objectSuffix}`, 'classId': `${issuerId}.${classSuffix}`, 'state': 'ACTIVE', 'heroImage': { 'sourceUri': { 'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Hero image description' } } }, 'textModulesData': [ { 'header': 'Text module header', 'body': 'Text module body', 'id': 'TEXT_MODULE_ID' } ], 'linksModuleData': { 'uris': [ { 'uri': 'http://maps.google.com/', 'description': 'Link module URI description', 'id': 'LINK_MODULE_URI_ID' }, { 'uri': 'tel:6505555555', 'description': 'Link module tel description', 'id': 'LINK_MODULE_TEL_ID' } ] }, 'imageModulesData': [ { 'mainImage': { 'sourceUri': { 'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Image module description' } } }, 'id': 'IMAGE_MODULE_ID' } ], 'barcode': { 'type': 'QR_CODE', 'value': 'QR code' }, 'locations': [ { 'latitude': 37.424015499999996, 'longitude': -122.09259560000001 } ], 'seatInfo': { 'seat': { 'defaultValue': { 'language': 'en-US', 'value': '42' } }, 'row': { 'defaultValue': { 'language': 'en-US', 'value': 'G3' } }, 'section': { 'defaultValue': { 'language': 'en-US', 'value': '5' } }, 'gate': { 'defaultValue': { 'language': 'en-US', 'value': 'A' } }, }, 'ticketHolderName': 'Ticket holder name', 'ticketNumber': 'Ticket number' }; data += '--batch_createobjectbatch\n'; data += 'Content-Type: application/json\n\n'; data += 'POST /walletobjects/v1/eventTicketObject\n\n'; data += JSON.stringify(batchObject) + '\n\n'; } data += '--batch_createobjectbatch--'; // Invoke the batch API calls let response = await this.client.context._options.auth.request({ url: 'https://walletobjects.googleapis.com/batch', method: 'POST', data: data, headers: { // `boundary` is the delimiter between API calls in the batch request 'Content-Type': 'multipart/mixed; boundary=batch_createobjectbatch' } }); console.log('Batch insert response'); console.log(response); }
رفتن
برای شروع یکپارچهسازی در Go، به نمونههای کد کامل ما در GitHub مراجعه کنید نمونههای کد در Github.
// Batch create Google Wallet objects from an existing class. func (d *demoEventticket) batchCreateObjects(issuerId, classSuffix string) { data := "" for i := 0; i < 3; i++ { objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_") eventticketObject := new(walletobjects.EventTicketObject) eventticketObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) eventticketObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) eventticketObject.TicketHolderName = "Ticket holder name" eventticketObject.TicketNumber = "Ticket number" eventticketObject.State = "ACTIVE" eventticketJson, _ := json.Marshal(eventticketObject) batchObject := fmt.Sprintf("%s", eventticketJson) data += "--batch_createobjectbatch\n" data += "Content-Type: application/json\n\n" data += "POST /walletobjects/v1/eventTicketObject\n\n" data += batchObject + "\n\n" } data += "--batch_createobjectbatch--" res, err := d.credentials.Client(oauth2.NoContext).Post("https://walletobjects.googleapis.com/batch", "multipart/mixed; boundary=batch_createobjectbatch", bytes.NewBuffer([]byte(data))) if err != nil { fmt.Println(err) } else { b, _ := io.ReadAll(res.Body) fmt.Printf("Batch insert response:\n%s\n", b) } }