ويتناول هذا المستند بعض الأساليب التي يمكنك استخدامها لتحسين أداء تطبيقك. في بعض الحالات، يتم استخدام أمثلة من واجهات برمجة تطبيقات أخرى أو واجهات برمجة تطبيقات عامة لتوضيح الأفكار المعروضة. ومع ذلك، تنطبق المفاهيم نفسها على Google Wallet API.
الضغط باستخدام gzip
وهناك طريقة سهلة وملائمة لتقليل معدل نقل البيانات اللازم لكل طلب، وهي تمكين الضغط بتنسيق gzip. وعلى الرغم من أن هذا يتطلب وقتًا إضافيًا لوحدة المعالجة المركزية (CPU) لفك ضغط النتائج، فإن المقايضة مع تكاليف الشبكة عادةً ما تجعل الأمر مفيدًا للغاية.
لتلقي استجابة بترميز gzip، عليك عمل شيئين: ضبط العنوان Accept-Encoding
وتعديل وكيل المستخدم بحيث يتضمن السلسلة gzip
. في ما يلي مثال على عناوين HTTP تم تشكيلها بشكل صحيح لتفعيل ضغط gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
استخدام الموارد الجزئية
هناك طريقة أخرى لتحسين أداء طلبات البيانات من واجهة برمجة التطبيقات، وهي إرسال واستلام جزء البيانات الذي يهمّك فقط. ويتيح ذلك لتطبيقك تجنب نقل الحقول غير الضرورية وتحليلها وتخزينها، حتى يتمكن من استخدام الموارد بشكل أكثر فعالية، بما في ذلك الشبكة ووحدة المعالجة المركزية (CPU) والذاكرة.
هناك نوعان من الطلبات الجزئية:
- الردّ الجزئي: طلب يمكنك من خلاله تحديد الحقول المطلوب تضمينها في الردّ (استخدِم مَعلمة الطلب
fields
). - رمز التصحيح: طلب تعديل يمكنك من خلاله إرسال الحقول التي تريد تغييرها فقط (استخدِم فعل HTTP
PATCH
).
يتوفّر مزيد من التفاصيل حول إرسال طلبات جزئية في الأقسام التالية.
ردّ جزئي
يرسل الخادم تلقائيًا التمثيل الكامل للمورد بعد معالجة الطلبات. للحصول على أداء أفضل، يمكنك أن تطلب من الخادم إرسال الحقول التي تحتاجها فقط والحصول على ردّ جزئي بدلاً من ذلك.
لطلب استجابة جزئية، استخدِم مَعلمة طلب fields
لتحديد الحقول التي تريد عرضها. يمكنك استخدام هذه المعلمة مع أي طلب يعرض بيانات الاستجابة.
يُرجى العِلم أنّ مَعلمة fields
تؤثر فقط في بيانات الردّ. فلن يؤثر ذلك على البيانات التي تحتاج إلى إرسالها، إن وجدت. لتقليل كمية البيانات التي ترسلها عند تعديل الموارد، استخدِم طلب تصحيح.
مثال
يوضح المثال التالي استخدام المعلمة fields
مع عنصر تجريبي عام (خيالي) واجهة برمجة التطبيقات.
طلب بسيط: يحذف طلب 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: { ... }
، لا يجب تضمين "data
" في مواصفاتfields
. يؤدي تضمين كائن البيانات مع مواصفات حقول مثلdata/a/b
إلى حدوث خطأ. بدلاً من ذلك، يمكنك استخدام إحدى مواصفاتfields
مثلa/b
. - يمكنك استخدام أداة اختيار فرعية لطلب مجموعة من الحقول الفرعية المحدّدة للمصفوفات أو الكائنات عن طريق وضع التعبيرات بين قوسين "
( )
".على سبيل المثال: تعرض
fields=items(id,author/email)
معرّف السلعة وعنوان البريد الإلكتروني للمؤلف فقط لكل عنصر في مصفوفة السلع. ويمكنك أيضًا تحديد حقل فرعي واحد، حيث تكون السمةfields=items(id)
معادِلة للحقلfields=items/id
. - استخدِم أحرف البدل في اختيارات الحقول، إذا لزم الأمر.
على سبيل المثال: يختار
fields=items/pagemap/*
كل العناصر في خريطة صفحات.
مزيد من الأمثلة على استخدام مَعلمة الحقول
تتضمّن الأمثلة أدناه أوصافًا لكيفية تأثير قيمة مَعلمة fields
في الاستجابة.
ملاحظة: كما هو الحال مع جميع قيم مَعلمات طلب البحث، يجب ترميز قيمة مَعلمة fields
بعنوان URL. ولتسهيل القراءة، تتجاهل الأمثلة الواردة في هذا المستند الترميز.
- حدِّد الحقول التي تريد عرضها أو اختَر اختيارات الحقول.
- قيمة معلمة الطلب
fields
هي قائمة حقول مفصولة بفواصل، ويتم تحديد كل حقل وفقًا لجذر الاستجابة. وبالتالي، إذا كنت تجري عملية list، يكون الرد عبارة عن مجموعة، وعادةً ما يتضمن مصفوفة من الموارد. إذا كنت تنفذ عملية تؤدي إلى إرجاع مورد واحد، فسيتم تحديد حقول ذات صلة بهذا المورد. إذا كان الحقل الذي تحدده هو صفيف (أو جزءًا منه)، يعرض الخادم الجزء المحدد من جميع العناصر في الصفيف.
في ما يلي بعض الأمثلة على مستوى المجموعة:
أمثلة التأثير 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
، يرسل مرة أخرى رمز حالة HTTP 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 الأقدم والتحديث الجزئي.
يوضّح المثال القصير أدناه كيف يؤدي استخدام رمز التصحيح إلى تقليل البيانات التي تحتاج إلى إرسالها لإجراء تعديل بسيط.
مثال
يعرض هذا المثال طلب تصحيح بسيط لتحديث عنوان "نسخة تجريبية" عامة (خيالية) فقط مورد واجهة برمجة التطبيقات. يحتوي المورد أيضًا على تعليق ومجموعة من الخصائص والحالة والعديد من الحقول الأخرى، ولكن هذا الطلب يرسل فقط الحقل 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 فارغة.
ملاحظة بشأن الصفائف: تستبدل طلبات التصحيح التي تحتوي على صفائف المصفوفة الحالية بالمصفوفة التي تقدّمها. لا يمكنك تعديل عناصر أو إضافتها أو حذفها في مصفوفة بشكل مجزّأ.
استخدام رمز التصحيح في دورة القراءة والتعديل والكتابة
قد يكون من المفيد البدء باسترداد رد جزئي بالبيانات التي تريد تعديلها. ويُعدّ هذا الإجراء مهمًا على وجه الخصوص للموارد التي تستخدم علامات ETag، لأنّه يجب تقديم قيمة ETag الحالية في عنوان HTTP If-Match
لتعديل المورد بنجاح. بعد الحصول على البيانات، يمكنك تعديل القيم التي تريد تغييرها وإعادة التمثيل الجزئي المعدَّل مع طلب تصحيح. في ما يلي مثال يفترض أن المورد التجريبي يستخدم علامات ETag:
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. */ }, }
يستجيب الخادم برمز حالة OK HTTP 200، والتمثيل الجزئي للمورد الذي تم تحديثه:
200 OK
{ "etag": "newETagString" "title": "", /* Title is cleared; deleted comment field is missing. */ "characteristics": { "length": "short", "level": "10", /* Value is updated.*/ "followers": ["Jo" "Liz"], /* New follower Liz is present; deleted Will is missing. */ "accuracy": "high" /* New characteristic is present. */ } }
إنشاء طلب تصحيح مباشرةً
بالنسبة إلى بعض طلبات التصحيح، يجب أن تبني هذه الطلبات على البيانات التي استعدتها سابقًا. على سبيل المثال، إذا أردت إضافة عنصر إلى مصفوفة ولا تريد فقدان أي من عناصر الصفيف الموجودة، يجب عليك الحصول على البيانات الحالية أولاً. وبالمثل، إذا كانت واجهة برمجة التطبيقات تستخدم علامات ETag، عليك إرسال قيمة ETag السابقة مع طلبك لتعديل المورد بنجاح.
ملاحظة: يمكنك استخدام عنوان HTTP يتضمّن "If-Match: *"
لفرض إرسال رمز التصحيح عندما تكون علامات ETag قيد الاستخدام. إذا قمت بذلك، فلن تحتاج إلى إجراء القراءة قبل الكتابة.
في الحالات الأخرى، يمكنك إنشاء طلب التصحيح مباشرةً، دون استرداد البيانات الحالية أولاً. على سبيل المثال، يمكنك بسهولة إعداد طلب رمز تصحيح يعدّل حقل إلى قيمة جديدة أو يضيف حقلاً جديدًا. يُرجى الاطّلاع على المثال أدناه:
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 } }
مع هذا الطلب، إذا كان حقل التعليق يحتوي على قيمة حالية، ستحل القيمة الجديدة محلها؛ وإلا يتم تعيينها على القيمة الجديدة. وبالمثل، إذا كانت هناك خاصية حجم، يتم استبدال قيمتها؛ وإذا لم يكن كذلك، فسيتم إنشاؤه. وتتم إزالة حقل الدقة في حال ضبطه.
التعامل مع الرد على رمز التصحيح
بعد معالجة طلب تصحيح صالح، تعرض واجهة برمجة التطبيقات رمز استجابة HTTP 200 OK
مع التمثيل الكامل للمورد المعدّل. في حال استخدام علامات ETag بواسطة واجهة برمجة التطبيقات، يعدِّل الخادم قيم ETag عند معالجة طلب تصحيح بنجاح، كما هو الحال مع PUT
.
يعرض طلب التصحيح تمثيل المورد بالكامل ما لم تستخدم المعلمة fields
لتقليل كمية البيانات التي يعرضها.
إذا نتج عن طلب التصحيح حالة مورد جديدة غير صالحة من ناحية البنية أو دلاليًا، يعرض الخادم رمز حالة HTTP 400 Bad Request
أو 422 Unprocessable Entity
وتبقى حالة المورد بدون تغيير. على سبيل المثال، إذا حاولت حذف قيمة حقل مطلوب، سيعرض الخادم خطأ.
التدوين البديل عندما لا يكون فعل PATCH HTTP متاحًا
إذا كان جدار الحماية لا يسمح بطلبات 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
لبدء الدمج في 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<GenericObject> callback = new JsonBatchCallback<GenericObject>() { // Invoked if the request was successful public void onSuccess(GenericObject 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/generic/rest/v1/genericobject GenericObject batchObject = new GenericObject() .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")) .setCardTitle( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Generic card title"))) .setHeader( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("Generic header"))) .setHexBackgroundColor("#4285f4") .setLogo( new Image() .setSourceUri( new ImageUri() .setUri( "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Generic card logo")))); service.genericobject().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/generic/rest/v1/genericobject $batchObject = new GenericObject([ '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' ]), 'cardTitle' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Generic card title' ]) ]), 'header' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Generic header' ]) ]), 'hexBackgroundColor' => '#4285f4', 'logo' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Generic card logo' ]) ]) ]) ]); $batch->add($this->service->genericobject->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
لبدء عملية الدمج في بايثون، يُرجى الرجوع إلى عيّنات من الرموز البرمجية على 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/generic/rest/v1/genericobject 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' }, 'cardTitle': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic card title' } }, 'header': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic header' } }, 'hexBackgroundColor': '#4285f4', 'logo': { 'sourceUri': { 'uri': 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic card logo' } } } } batch.add(self.client.genericobject().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/generic/rest/v1/genericobject GenericObject batchObject = new GenericObject { 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" }, CardTitle = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Generic card title" } }, Header = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Generic header" } }, HexBackgroundColor = "#4285f4", Logo = new Image { SourceUri = new ImageUri { Uri = "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Generic card logo" } }, } }; data += "--batch_createobjectbatch\n"; data += "Content-Type: application/json\n\n"; data += "POST /walletobjects/v1/genericObject/\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/generic/rest/v1/genericobject 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' }, 'cardTitle': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic card title' } }, 'header': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic header' } }, 'hexBackgroundColor': '#4285f4', 'logo': { 'sourceUri': { 'uri': 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Generic card logo' } } } }; data += '--batch_createobjectbatch\n'; data += 'Content-Type: application/json\n\n'; data += 'POST /walletobjects/v1/genericObject\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 *demoGeneric) batchCreateObjects(issuerId, classSuffix string) { data := "" for i := 0; i < 3; i++ { objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_") genericObject := new(walletobjects.GenericObject) genericObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) genericObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) genericObject.State = "ACTIVE" genericObject.Barcode = &walletobjects.Barcode{ Type: "QR_CODE", Value: "QR code", } genericObject.CardTitle = &walletobjects.LocalizedString{ DefaultValue: &walletobjects.TranslatedString{ Language: "en-us", Value: "Card title", }, } genericObject.Header = &walletobjects.LocalizedString{ DefaultValue: &walletobjects.TranslatedString{ Language: "en-us", Value: "Header", }, } genericJson, _ := json.Marshal(genericObject) batchObject := fmt.Sprintf("%s", genericJson) data += "--batch_createobjectbatch\n" data += "Content-Type: application/json\n\n" data += "POST /walletobjects/v1/genericObject\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) } }