এই ডকুমেন্টে আপনার অ্যাপ্লিকেশনের কর্মক্ষমতা উন্নত করার জন্য আপনি যে কৌশলগুলি ব্যবহার করতে পারেন সেগুলি অন্তর্ভুক্ত করা হয়েছে। কিছু ক্ষেত্রে, অন্যান্য API বা জেনেরিক API থেকে উদাহরণগুলি উপস্থাপিত ধারণাগুলি ব্যাখ্যা করার জন্য ব্যবহার করা হয়। তবে, একই ধারণাগুলি Google Wallet API-এর ক্ষেত্রে প্রযোজ্য।
gzip ব্যবহার করে কম্প্রেশন
প্রতিটি অনুরোধের জন্য প্রয়োজনীয় ব্যান্ডউইথ কমানোর একটি সহজ এবং সুবিধাজনক উপায় হল gzip কম্প্রেশন সক্ষম করা। যদিও ফলাফল আনকম্প্রেস করার জন্য অতিরিক্ত CPU সময় প্রয়োজন, নেটওয়ার্ক খরচের সাথে বিনিময় সাধারণত এটিকে খুব লাভজনক করে তোলে।
gzip-এনকোডেড রেসপন্স পেতে হলে আপনাকে দুটি জিনিস করতে হবে: একটি Accept-Encoding হেডার সেট করুন, এবং আপনার ব্যবহারকারী এজেন্টকে gzip স্ট্রিং ধারণ করার জন্য পরিবর্তন করুন। gzip কম্প্রেশন সক্ষম করার জন্য সঠিকভাবে তৈরি HTTP হেডারের একটি উদাহরণ এখানে দেওয়া হল:
Accept-Encoding: gzip User-Agent: my program (gzip)
আংশিক সম্পদ নিয়ে কাজ করা
আপনার API কলের কর্মক্ষমতা উন্নত করার আরেকটি উপায় হল আপনার আগ্রহের ডেটার শুধুমাত্র সেই অংশটি পাঠানো এবং গ্রহণ করা। এটি আপনার অ্যাপ্লিকেশনকে অপ্রয়োজনীয় ক্ষেত্রগুলি স্থানান্তর, পার্সিং এবং সংরক্ষণ এড়াতে দেয়, যাতে এটি নেটওয়ার্ক, CPU এবং মেমরি সহ সংস্থানগুলি আরও দক্ষতার সাথে ব্যবহার করতে পারে।
আংশিক অনুরোধ দুই ধরণের আছে:
- আংশিক প্রতিক্রিয়া : একটি অনুরোধ যেখানে আপনি প্রতিক্রিয়ায় কোন ক্ষেত্রগুলি অন্তর্ভুক্ত করবেন তা নির্দিষ্ট করেন (
fieldsঅনুরোধ প্যারামিটার ব্যবহার করুন)। - প্যাচ : একটি আপডেট অনুরোধ যেখানে আপনি কেবল সেই ক্ষেত্রগুলি পাঠান যা আপনি পরিবর্তন করতে চান (
PATCHHTTP ক্রিয়া ব্যবহার করুন)।
আংশিক অনুরোধ করার বিষয়ে আরও বিশদ নিম্নলিখিত বিভাগগুলিতে সরবরাহ করা হয়েছে।
আংশিক প্রতিক্রিয়া
ডিফল্টরূপে, সার্ভার অনুরোধ প্রক্রিয়াকরণের পরে একটি রিসোর্সের সম্পূর্ণ প্রতিনিধিত্ব ফেরত পাঠায়। আরও ভালো পারফরম্যান্সের জন্য, আপনি সার্ভারকে শুধুমাত্র আপনার প্রয়োজনীয় ক্ষেত্রগুলি পাঠাতে বলতে পারেন এবং পরিবর্তে একটি আংশিক প্রতিক্রিয়া পেতে পারেন।
আংশিক প্রতিক্রিয়ার অনুরোধ করতে, আপনি যে ক্ষেত্রগুলি ফেরত চান তা নির্দিষ্ট করতে fields request প্যারামিটার ব্যবহার করুন। আপনি এই প্যারামিটারটি যেকোনো অনুরোধের সাথে ব্যবহার করতে পারেন যা প্রতিক্রিয়া ডেটা ফেরত দেয়।
মনে রাখবেন যে fields প্যারামিটার শুধুমাত্র প্রতিক্রিয়া ডেটাকে প্রভাবিত করে; এটি আপনার প্রয়োজন এমন ডেটাকে প্রভাবিত করে না, যদি থাকে। রিসোর্স পরিবর্তন করার সময় আপনার পাঠানো ডেটার পরিমাণ কমাতে, একটি প্যাচ অনুরোধ ব্যবহার করুন।
উদাহরণ
নিম্নলিখিত উদাহরণটি একটি জেনেরিক (কাল্পনিক) "ডেমো" API-এর সাথে 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ব্যবহার করেaফিল্ডের মধ্যে নেস্টেডbফিল্ড নির্বাচন করুন;a/b/cব্যবহার করেbএর মধ্যে নেস্টেডcফিল্ড নির্বাচন করুন।ব্যতিক্রম: "ডেটা" র্যাপার ব্যবহার করে এমন API প্রতিক্রিয়াগুলির জন্য, যেখানে প্রতিক্রিয়াটি
data: { ... }মতো দেখতেdataঅবজেক্টের মধ্যে নেস্ট করা হয়: { ... },fieldsস্পেসিফিকেশনে "data" অন্তর্ভুক্ত করবেন না। ডেটা অবজেক্টকেdata/a/bমতো ফিল্ড স্পেসিফিকেশন সহ অন্তর্ভুক্ত করলে ত্রুটি দেখা দেয়। পরিবর্তে, কেবলa/bমতোfieldsস্পেসিফিকেশন ব্যবহার করুন। - বন্ধনীতে "
( )" এক্সপ্রেশন স্থাপন করে অ্যারে বা বস্তুর নির্দিষ্ট উপ-ক্ষেত্রের একটি সেট অনুরোধ করতে একটি সাব-সিলেক্টর ব্যবহার করুন।উদাহরণস্বরূপ:
fields=items(id,author/email)আইটেম অ্যারের প্রতিটি উপাদানের জন্য শুধুমাত্র আইটেম আইডি এবং লেখকের ইমেল ফেরত দেয়। আপনি একটি একক সাব-ফিল্ডও নির্দিষ্ট করতে পারেন, যেখানেfields=items(id)fields=items/idএর সমতুল্য। - প্রয়োজনে ফিল্ড নির্বাচনে ওয়াইল্ডকার্ড ব্যবহার করুন।
উদাহরণস্বরূপ:
fields=items/pagemap/*একটি পেজম্যাপের সমস্ত বস্তু নির্বাচন করে।
ক্ষেত্র পরামিতি ব্যবহারের আরও উদাহরণ
নিচের উদাহরণগুলিতে fields প্যারামিটারের মান কীভাবে প্রতিক্রিয়াকে প্রভাবিত করে তার বর্ণনা অন্তর্ভুক্ত রয়েছে।
দ্রষ্টব্য: সকল কোয়েরি প্যারামিটার মানের মতো, fields প্যারামিটার মান অবশ্যই URL এনকোডেড হতে হবে। আরও ভালো পঠনযোগ্যতার জন্য, এই নথির উদাহরণগুলিতে এনকোডিং বাদ দেওয়া হয়েছে।
- আপনি যে ক্ষেত্রগুলি ফেরত চান তা চিহ্নিত করুন, অথবা ক্ষেত্র নির্বাচন করুন।
-
fieldsরিকোয়েস্ট প্যারামিটারের মান হল কমা দ্বারা পৃথক করা ফিল্ডের একটি তালিকা, এবং প্রতিটি ফিল্ড প্রতিক্রিয়ার মূলের সাথে সম্পর্কিতভাবে নির্দিষ্ট করা হয়। সুতরাং, যদি আপনি একটি তালিকা অপারেশন সম্পাদন করেন, তাহলে প্রতিক্রিয়াটি একটি সংগ্রহ এবং এতে সাধারণত সম্পদের একটি অ্যারে অন্তর্ভুক্ত থাকে। যদি আপনি এমন একটি অপারেশন সম্পাদন করেন যা একটি একক সম্পদ প্রদান করে, তাহলে ক্ষেত্রগুলি সেই সম্পদের সাথে সম্পর্কিতভাবে নির্দিষ্ট করা হয়। আপনার নির্বাচিত ক্ষেত্রটি যদি একটি অ্যারের (অথবা অংশ) হয়, তাহলে সার্ভার অ্যারের সমস্ত উপাদানের নির্বাচিত অংশ প্রদান করে।
এখানে কিছু সংগ্রহ-স্তরের উদাহরণ দেওয়া হল:উদাহরণ প্রভাব itemsআইটেম অ্যারের সমস্ত উপাদান ফেরত পাঠায়, প্রতিটি উপাদানের সমস্ত ক্ষেত্র সহ, কিন্তু অন্য কোনও ক্ষেত্র নয়। etag,itemsetagক্ষেত্র এবং আইটেম অ্যারের সকল উপাদান উভয়ই ফেরত পাঠায়।items/titleআইটেম অ্যারের সকল উপাদানের জন্য শুধুমাত্র titleক্ষেত্রটি ফেরত পাঠায়।
যখনই একটি নেস্টেড ফিল্ড রিটার্ন করা হয়, তখন রেসপন্সে এনক্লোজিং প্যারেন্ট অবজেক্ট অন্তর্ভুক্ত থাকে। প্যারেন্ট ফিল্ডগুলিতে অন্য কোনও চাইল্ড ফিল্ড অন্তর্ভুক্ত থাকে না যদি না সেগুলি স্পষ্টভাবে নির্বাচিত হয়।context/facets/labelfacetsঅ্যারের সকল সদস্যের জন্য শুধুমাত্রlabelক্ষেত্রটি ফেরত দেয়, যা নিজেইcontextobject এর অধীনে নেস্টেড থাকে।items/pagemap/*/titleআইটেম অ্যারের প্রতিটি উপাদানের জন্য, pagemapশিশু সকল বস্তুর শুধুমাত্রtitleক্ষেত্র (যদি উপস্থিত থাকে) প্রদান করে।
এখানে কিছু রিসোর্স-স্তরের উদাহরণ দেওয়া হল:উদাহরণ প্রভাব titleঅনুরোধকৃত রিসোর্সের titleক্ষেত্রটি প্রদান করে।author/uriঅনুরোধকৃত রিসোর্সে authorঅবজেক্টেরuriসাব-ফিল্ড রিটার্ন করে।links/*/hreflinksসন্তান সকল বস্তুরhrefক্ষেত্র প্রদান করে। - উপ-নির্বাচন ব্যবহার করে শুধুমাত্র নির্দিষ্ট ক্ষেত্রের কিছু অংশের জন্য অনুরোধ করুন।
- ডিফল্টরূপে, যদি আপনার অনুরোধ নির্দিষ্ট ক্ষেত্রগুলি নির্দিষ্ট করে, সার্ভারটি বস্তু বা অ্যারের উপাদানগুলিকে সম্পূর্ণরূপে ফেরত দেয়। আপনি এমন একটি প্রতিক্রিয়া নির্দিষ্ট করতে পারেন যাতে কেবল নির্দিষ্ট উপ-ক্ষেত্র অন্তর্ভুক্ত থাকে। আপনি নীচের উদাহরণের মতো "
( )" উপ-নির্বাচন সিনট্যাক্স ব্যবহার করে এটি করেন।উদাহরণ প্রভাব 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"
}
},
...
]
} দ্রষ্টব্য: যেসব API ডেটা পেজিনেশনের জন্য কোয়েরি প্যারামিটার সমর্থন করে (উদাহরণস্বরূপ, maxResults এবং nextPageToken ), প্রতিটি কোয়েরির ফলাফলকে একটি পরিচালনাযোগ্য আকারে কমাতে এই প্যারামিটারগুলি ব্যবহার করুন। অন্যথায়, আংশিক প্রতিক্রিয়ার মাধ্যমে সম্ভাব্য কর্মক্ষমতা লাভ অর্জন করা সম্ভব নাও হতে পারে।
প্যাচ (আংশিক আপডেট)
রিসোর্স পরিবর্তন করার সময় আপনি অপ্রয়োজনীয় ডেটা পাঠানো এড়াতে পারেন। শুধুমাত্র আপনার পরিবর্তন করা নির্দিষ্ট ক্ষেত্রগুলির জন্য আপডেট করা ডেটা পাঠাতে, HTTP PATCH ক্রিয়াটি ব্যবহার করুন। এই নথিতে বর্ণিত প্যাচ শব্দার্থবিদ্যা আংশিক আপডেটের পুরানো GData বাস্তবায়নের চেয়ে আলাদা (এবং সহজ)।
নিচের ছোট উদাহরণটি দেখায় যে প্যাচ ব্যবহার করলে কীভাবে একটি ছোট আপডেট করার জন্য আপনার প্রয়োজনীয় ডেটা কমানো যায়।
উদাহরণ
এই উদাহরণে একটি সাধারণ (কাল্পনিক) "ডেমো" 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 প্যারামিটার সহ একটি প্যাচ অনুরোধ ব্যবহার করুন।
একটি প্যাচ অনুরোধের শব্দার্থবিদ্যা
প্যাচ রিকোয়েস্টের মূল অংশে শুধুমাত্র সেই রিসোর্স ফিল্ডগুলি অন্তর্ভুক্ত থাকে যা আপনি পরিবর্তন করতে চান। যখন আপনি একটি ফিল্ড নির্দিষ্ট করেন, তখন আপনাকে অবশ্যই যেকোনো এনক্লোজিং প্যারেন্ট অবজেক্ট অন্তর্ভুক্ত করতে হবে, ঠিক যেমন এনক্লোজিং প্যারেন্টগুলিকে আংশিক প্রতিক্রিয়া সহ ফেরত পাঠানো হয়। আপনার পাঠানো পরিবর্তিত ডেটা যদি প্যারেন্ট অবজেক্টের ডেটাতে মার্জ করা হয়, যদি থাকে।
- যোগ করুন: এমন একটি ক্ষেত্র যোগ করতে যা ইতিমধ্যে বিদ্যমান নেই, নতুন ক্ষেত্র এবং তার মান উল্লেখ করুন।
- পরিবর্তন: বিদ্যমান ক্ষেত্রের মান পরিবর্তন করতে, ক্ষেত্রটি নির্দিষ্ট করুন এবং এটিকে নতুন মানে সেট করুন।
- Delete: একটি ক্ষেত্র মুছে ফেলার জন্য, ক্ষেত্রটি নির্দিষ্ট করুন এবং এটিকে
nullএ সেট করুন। উদাহরণস্বরূপ,"comment": null। আপনিnullএ সেট করে একটি সম্পূর্ণ বস্তু (যদি এটি পরিবর্তনযোগ্য হয়) মুছে ফেলতে পারেন। আপনি যদি Java API ক্লায়েন্ট লাইব্রেরি ব্যবহার করেন, তাহলেData.NULL_STRINGব্যবহার করুন; বিস্তারিত জানার জন্য, JSON null দেখুন।
অ্যারে সম্পর্কে দ্রষ্টব্য: যেসব প্যাচ রিকোয়েস্টে অ্যারে থাকে, সেগুলি আপনার দেওয়া অ্যারে দিয়ে বিদ্যমান অ্যারে প্রতিস্থাপন করে। আপনি কোনও অ্যারেতে আইটেমগুলিকে টুকরো টুকরো করে পরিবর্তন, যোগ বা মুছে ফেলতে পারবেন না।
পঠন-পরিবর্তন-লেখা চক্রে প্যাচ ব্যবহার করা
আপনি যে ডেটা পরিবর্তন করতে চান তার আংশিক প্রতিক্রিয়া পুনরুদ্ধার করে শুরু করা একটি কার্যকর অনুশীলন হতে পারে। এটি বিশেষ করে ETags ব্যবহারকারী রিসোর্সের জন্য গুরুত্বপূর্ণ, কারণ রিসোর্সটি সফলভাবে আপডেট করার জন্য আপনাকে If-Match HTTP হেডারে বর্তমান ETag মান প্রদান করতে হবে। ডেটা পাওয়ার পরে, আপনি যে মানগুলি পরিবর্তন করতে চান তা পরিবর্তন করতে পারেন এবং পরিবর্তিত আংশিক উপস্থাপনাটি একটি প্যাচ অনুরোধের সাথে ফেরত পাঠাতে পারেন। এখানে একটি উদাহরণ দেওয়া হল যা ধরে নেয় যে ডেমো রিসোর্স 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
{
"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. */
}
}সরাসরি একটি প্যাচ অনুরোধ তৈরি করা
কিছু প্যাচ অনুরোধের জন্য, আপনাকে পূর্বে পুনরুদ্ধার করা ডেটার উপর ভিত্তি করে সেগুলি তৈরি করতে হবে। উদাহরণস্বরূপ, যদি আপনি একটি অ্যারেতে একটি আইটেম যোগ করতে চান এবং বিদ্যমান অ্যারের কোনও উপাদান হারাতে না চান, তাহলে আপনাকে প্রথমে বিদ্যমান ডেটা পেতে হবে। একইভাবে, যদি কোনও API ETags ব্যবহার করে, তাহলে রিসোর্সটি সফলভাবে আপডেট করার জন্য আপনাকে আপনার অনুরোধের সাথে পূর্ববর্তী ETag মান পাঠাতে হবে।
দ্রষ্টব্য: ETags ব্যবহারের সময় একটি প্যাচ জোর করে প্রবেশ করানোর জন্য আপনি "If-Match: *" HTTP হেডার ব্যবহার করতে পারেন। যদি আপনি এটি করেন, তাহলে লেখার আগে আপনাকে পঠন করতে হবে না।
তবে অন্যান্য পরিস্থিতিতে, আপনি বিদ্যমান ডেটা পুনরুদ্ধার না করেই সরাসরি প্যাচ অনুরোধ তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি সহজেই একটি প্যাচ অনুরোধ সেট আপ করতে পারেন যা একটি ক্ষেত্রকে একটি নতুন মান আপডেট করে বা একটি নতুন ক্ষেত্র যোগ করে। এখানে একটি উদাহরণ দেওয়া হল:
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 পরিবর্তিত রিসোর্সের সম্পূর্ণ উপস্থাপনা সহ একটি 200 OK HTTP প্রতিক্রিয়া কোড প্রদান করে। যদি API দ্বারা ETags ব্যবহার করা হয়, তাহলে সার্ভারটি PUT এর মতোই একটি প্যাচ অনুরোধ সফলভাবে প্রক্রিয়াকরণের সময় ETag মান আপডেট করে।
প্যাচ রিকোয়েস্ট সম্পূর্ণ রিসোর্স রিপাের্টেশন ফেরত দেয়, যদি না আপনি fields প্যারামিটার ব্যবহার করে ডেটার পরিমাণ কমিয়ে দেন।
যদি কোনও প্যাচ অনুরোধের ফলে একটি নতুন রিসোর্স স্টেট তৈরি হয় যা সিনট্যাক্টিক বা শব্দার্থিকভাবে অবৈধ হয়, তাহলে সার্ভারটি একটি 400 Bad Request অথবা 422 Unprocessable Entity HTTP স্ট্যাটাস কোড ফেরত পাঠায় এবং রিসোর্স স্টেট অপরিবর্তিত থাকে। উদাহরণস্বরূপ, যদি আপনি একটি প্রয়োজনীয় ক্ষেত্রের মান মুছে ফেলার চেষ্টা করেন, তাহলে সার্ভার একটি ত্রুটি ফেরত পাঠায়।
PATCH HTTP ক্রিয়া সমর্থিত না হলে বিকল্প স্বরলিপি
যদি আপনার ফায়ারওয়াল HTTP PATCH অনুরোধগুলিকে অনুমতি না দেয়, তাহলে একটি HTTP POST অনুরোধ করুন এবং ওভাররাইড হেডারটি PATCH এ সেট করুন, যেমনটি নীচে দেখানো হয়েছে:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
প্যাচ এবং আপডেটের মধ্যে পার্থক্য
বাস্তবে, যখন আপনি HTTP PUT ক্রিয়া ব্যবহার করে আপডেট অনুরোধের জন্য ডেটা পাঠান, তখন আপনাকে কেবল সেই ক্ষেত্রগুলি পাঠাতে হবে যা হয় প্রয়োজনীয় বা ঐচ্ছিক; যদি আপনি সার্ভার দ্বারা সেট করা ক্ষেত্রগুলির জন্য মান পাঠান, তবে সেগুলি উপেক্ষা করা হয়। যদিও এটি আংশিক আপডেট করার অন্য উপায় বলে মনে হতে পারে, এই পদ্ধতির কিছু সীমাবদ্ধতা রয়েছে। HTTP PUT ক্রিয়া ব্যবহার করে আপডেটগুলির ক্ষেত্রে, প্রয়োজনীয় প্যারামিটার সরবরাহ না করলে অনুরোধ ব্যর্থ হয় এবং যদি আপনি ঐচ্ছিক প্যারামিটার সরবরাহ না করেন তবে এটি পূর্বে সেট করা ডেটা সাফ করে।
এই কারণে প্যাচ ব্যবহার করা অনেক বেশি নিরাপদ। আপনি কেবল সেই ক্ষেত্রগুলির জন্য ডেটা সরবরাহ করেন যা আপনি পরিবর্তন করতে চান; যে ক্ষেত্রগুলি আপনি বাদ দেন সেগুলি সাফ করা হয় না। এই নিয়মের একমাত্র ব্যতিক্রম পুনরাবৃত্তিকারী উপাদান বা অ্যারের ক্ষেত্রে ঘটে: যদি আপনি তাদের সমস্ত বাদ দেন, তবে তারা যেমন আছে তেমনই থাকে; যদি আপনি তাদের মধ্যে কোনওটি প্রদান করেন, তবে পুরো সেটটি আপনার সরবরাহ করা সেট দিয়ে প্রতিস্থাপিত হয়।
Google Wallet-এ ব্যাচ অনুরোধ
গুগল ওয়ালেট এপিআই ক্লায়েন্টের সংযোগের সংখ্যা কমাতে API কলগুলিকে একসাথে ব্যাচিং সমর্থন করে। ব্যাচ অনুরোধ এবং প্রতিক্রিয়া কাঠামো সম্পর্কে আরও তথ্যের জন্য, ব্যাচের বিবরণ দেখুন।
নিম্নলিখিত নমুনা কোডটি ব্যাচিং অনুরোধগুলি প্রদর্শন করে। জাভা এবং পিএইচপি উদাহরণগুলি ক্লাস এবং অবজেক্ট তৈরি সহজ করার জন্য গুগল ওয়ালেট লাইব্রেরি ব্যবহার করে।
জাভা
জাভাতে আপনার ইন্টিগ্রেশন শুরু করতে, 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<FlightObject> callback = new JsonBatchCallback<FlightObject>() { // Invoked if the request was successful public void onSuccess(FlightObject 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/boarding-passes/rest/v1/flightobject FlightObject batchObject = new FlightObject() .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))) .setPassengerName("Passenger name") .setBoardingAndSeatingInfo( new BoardingAndSeatingInfo().setBoardingGroup("B").setSeatNumber("42")) .setReservationInfo(new ReservationInfo().setConfirmationCode("Confirmation code")); service.flightobject().insert(batchObject).queue(batch, callback); } // Invoke the batch API calls batch.execute(); }
পিএইচপি
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/boarding-passes/rest/v1/flightobject $batchObject = new FlightObject([ '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 ]) ], 'passengerName' => 'Passenger name', 'boardingAndSeatingInfo' => new BoardingAndSeatingInfo([ 'boardingGroup' => 'B', 'seatNumber' => '42' ]), 'reservationInfo' => new ReservationInfo([ 'confirmationCode' => 'Confirmation code' ]) ]); $batch->add($this->service->flightobject->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"; } }
পাইথন
পাইথনে আপনার ইন্টিগ্রেশন শুরু করতে, 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/boarding-passes/rest/v1/flightobject 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 }], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } } batch.add(self.client.flightobject().insert(body=batch_object)) # Invoke the batch API calls response = batch.execute() print('Batch complete')
সি#
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/boarding-passes/rest/v1/flightobject FlightObject batchObject = new FlightObject { 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 } }, PassengerName = "Passenger name", BoardingAndSeatingInfo = new BoardingAndSeatingInfo { BoardingGroup = "B", SeatNumber = "42" }, ReservationInfo = new ReservationInfo { ConfirmationCode = "Confirmation code" } }; data += "--batch_createobjectbatch\n"; data += "Content-Type: application/json\n\n"; data += "POST /walletobjects/v1/flightObject/\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); }
নোড.জেএস
নোডে আপনার ইন্টিগ্রেশন শুরু করতে, 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/boarding-passes/rest/v1/flightobject 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 } ], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } }; data += '--batch_createobjectbatch\n'; data += 'Content-Type: application/json\n\n'; data += 'POST /walletobjects/v1/flightObject\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-এ আমাদের সম্পূর্ণ কোড নমুনাগুলি দেখুন।
// Batch create Google Wallet objects from an existing class. func (d *demoFlight) batchCreateObjects(issuerId, classSuffix string) { data := "" for i := 0; i < 3; i++ { objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_") flightObject := new(walletobjects.FlightObject) flightObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) flightObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) flightObject.State = "ACTIVE" flightObject.PassengerName = "Passenger name" flightObject.ReservationInfo = &walletobjects.ReservationInfo{ ConfirmationCode: "Confirmation code", } flightJson, _ := json.Marshal(flightObject) batchObject := fmt.Sprintf("%s", flightJson) data += "--batch_createobjectbatch\n" data += "Content-Type: application/json\n\n" data += "POST /walletobjects/v1/flightObject\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) } }