এই নথিতে এমন কিছু কৌশল রয়েছে যা আপনি আপনার অ্যাপ্লিকেশনের কর্মক্ষমতা উন্নত করতে ব্যবহার করতে পারেন। কিছু ক্ষেত্রে, উপস্থাপিত ধারণাগুলিকে চিত্রিত করতে অন্যান্য API বা জেনেরিক API-এর উদাহরণ ব্যবহার করা হয়। যাইহোক, একই ধারণাগুলি Google Wallet API এর ক্ষেত্রে প্রযোজ্য।
জিজিপ ব্যবহার করে কম্প্রেশন
প্রতিটি অনুরোধের জন্য প্রয়োজনীয় ব্যান্ডউইথ কমানোর একটি সহজ এবং সুবিধাজনক উপায় হল জিজিপ কম্প্রেশন সক্ষম করা। যদিও ফলাফলগুলিকে কম্প্রেস করতে এর জন্য অতিরিক্ত CPU সময় প্রয়োজন, নেটওয়ার্ক খরচের সাথে ট্রেড-অফ সাধারণত এটিকে খুব সার্থক করে তোলে।
একটি gzip-এনকোড করা প্রতিক্রিয়া পাওয়ার জন্য আপনাকে দুটি জিনিস করতে হবে: একটি Accept-Encoding
শিরোনাম সেট করুন এবং স্ট্রিং gzip
ধারণ করতে আপনার ব্যবহারকারী এজেন্টকে পরিবর্তন করুন। এখানে gzip কম্প্রেশন সক্ষম করার জন্য সঠিকভাবে গঠিত HTTP হেডারগুলির একটি উদাহরণ রয়েছে:
Accept-Encoding: gzip User-Agent: my program (gzip)
আংশিক সম্পদ নিয়ে কাজ করা
আপনার API কলগুলির কার্যকারিতা উন্নত করার আরেকটি উপায় হল আপনার আগ্রহের ডেটার শুধুমাত্র অংশ পাঠানো এবং গ্রহণ করা৷ এটি আপনার অ্যাপ্লিকেশনটিকে অপ্রয়োজনীয় ক্ষেত্রগুলি স্থানান্তর, পার্সিং এবং সংরক্ষণ এড়াতে দেয়, যাতে এটি নেটওয়ার্ক সহ সংস্থানগুলি ব্যবহার করতে পারে, CPU, এবং মেমরি আরও দক্ষতার সাথে।
দুই ধরনের আংশিক অনুরোধ আছে:
- আংশিক প্রতিক্রিয়া : একটি অনুরোধ যেখানে আপনি প্রতিক্রিয়াতে কোন ক্ষেত্রগুলি অন্তর্ভুক্ত করতে হবে তা নির্দিষ্ট করেন (
fields
অনুরোধের প্যারামিটার ব্যবহার করুন)। - প্যাচ : একটি আপডেট অনুরোধ যেখানে আপনি শুধুমাত্র যে ক্ষেত্রগুলি পরিবর্তন করতে চান তা পাঠান (
PATCH
HTTP ক্রিয়া ব্যবহার করুন)।
আংশিক অনুরোধ করার বিষয়ে আরও বিশদ নিম্নলিখিত বিভাগে দেওয়া হয়েছে।
আংশিক প্রতিক্রিয়া
ডিফল্টরূপে, সার্ভার অনুরোধ প্রক্রিয়াকরণের পরে একটি সম্পদের সম্পূর্ণ উপস্থাপনা ফেরত পাঠায়। ভালো পারফরম্যান্সের জন্য, আপনি সার্ভারকে শুধুমাত্র আপনার প্রয়োজনীয় ক্ষেত্রগুলি পাঠাতে এবং পরিবর্তে একটি আংশিক প্রতিক্রিয়া পেতে বলতে পারেন।
একটি আংশিক প্রতিক্রিয়া অনুরোধ করতে, আপনি যে ক্ষেত্রগুলি ফেরত দিতে চান তা নির্দিষ্ট করতে fields
অনুরোধ প্যারামিটার ব্যবহার করুন৷ আপনি এই প্যারামিটারটি যেকোন অনুরোধের সাথে ব্যবহার করতে পারেন যা প্রতিক্রিয়া ডেটা প্রদান করে।
মনে রাখবেন যে 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)
আংশিক প্রতিক্রিয়া: উপরের অনুরোধের প্রতিক্রিয়া হিসাবে, সার্ভার একটি প্রতিক্রিয়া ফেরত পাঠায় যাতে একটি প্যারড-ডাউন আইটেম অ্যারের সাথে শুধুমাত্র এইচটিএমএল শিরোনাম এবং প্রতিটি আইটেমের দৈর্ঘ্য বৈশিষ্ট্যগত তথ্য অন্তর্ভুক্ত থাকে।
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
ব্যবহার করুন;b
এর মধ্যেc
নেস্টেড একটি ক্ষেত্র নির্বাচন করতেa/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,items
etag
ক্ষেত্র এবং আইটেম অ্যারের সমস্ত উপাদান উভয়ই প্রদান করে।items/title
আইটেম অ্যারের সমস্ত উপাদানের জন্য শুধুমাত্র title
ক্ষেত্র প্রদান করে।
যখনই একটি নেস্টেড ক্ষেত্র ফেরত দেওয়া হয়, তখন প্রতিক্রিয়ার মধ্যে বদ্ধ মূল বস্তু অন্তর্ভুক্ত থাকে। অভিভাবক ক্ষেত্রগুলি অন্য কোনও শিশু ক্ষেত্র অন্তর্ভুক্ত করে না যদি না সেগুলিও স্পষ্টভাবে নির্বাচিত হয়৷context/facets/label
facets
অ্যারের সমস্ত সদস্যের জন্য শুধুমাত্রlabel
ক্ষেত্রটি ফেরত দেয়, যা নিজেইcontext
অবজেক্টের অধীনে নেস্টেড।items/pagemap/*/title
আইটেম অ্যারের প্রতিটি উপাদানের জন্য, pagemap
শিশু সমস্ত বস্তুর শুধুমাত্রtitle
ক্ষেত্র (যদি উপস্থিত থাকে) প্রদান করে।
এখানে কিছু সম্পদ-স্তরের উদাহরণ রয়েছে:উদাহরণ প্রভাব title
অনুরোধ করা সম্পদের title
ক্ষেত্র ফেরত দেয়।author/uri
অনুরোধ করা সম্পদে author
অবজেক্টেরuri
সাব-ফিল্ড ফেরত দেয়।links/*/href
links
সন্তান যে সমস্ত বস্তুর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
পরামিতি সহ একটি প্যাচ অনুরোধ ব্যবহার করুন।
একটি প্যাচ অনুরোধের শব্দার্থবিদ্যা
প্যাচ অনুরোধের মূল অংশে শুধুমাত্র সেই রিসোর্স ক্ষেত্রগুলি রয়েছে যা আপনি পরিবর্তন করতে চান। যখন আপনি একটি ক্ষেত্র নির্দিষ্ট করেন, তখন আপনাকে অবশ্যই যেকোন এনক্লোসিং প্যারেন্ট অবজেক্ট অন্তর্ভুক্ত করতে হবে, ঠিক যেভাবে এনক্লোজিং প্যারেন্টকে আংশিক প্রতিক্রিয়া দিয়ে ফেরত দেওয়া হয়। আপনার পাঠানো পরিবর্তিত ডেটা মূল বস্তুর ডেটাতে মার্জ করা হয়, যদি একটি থাকে।
- যোগ করুন: ইতিমধ্যে বিদ্যমান নেই এমন একটি ক্ষেত্র যোগ করতে, নতুন ক্ষেত্র এবং এর মান উল্লেখ করুন।
- পরিবর্তন: একটি বিদ্যমান ক্ষেত্রের মান পরিবর্তন করতে, ক্ষেত্রটি নির্দিষ্ট করুন এবং এটিকে নতুন মান নির্ধারণ করুন।
- মুছুন: একটি ক্ষেত্র মুছে ফেলতে, ক্ষেত্রটি নির্দিষ্ট করুন এবং এটিকে
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. */ }, }
সার্ভারটি একটি 200 ওকে 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 মান পাঠাতে হবে।
দ্রষ্টব্য: আপনি একটি "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 পরিবর্তিত সম্পদের সম্পূর্ণ উপস্থাপনা সহ একটি 200 OK
HTTP প্রতিক্রিয়া কোড প্রদান করে। যদি ETagsগুলি API দ্বারা ব্যবহার করা হয়, সার্ভারটি ETag মানগুলি আপডেট করে যখন এটি একটি প্যাচ অনুরোধ সফলভাবে প্রক্রিয়া করে, ঠিক যেমন এটি PUT
এর সাথে করে।
প্যাচ রিকোয়েস্ট সম্পূর্ণ রিসোর্স রিপ্রেজেন্টেশন রিটার্ন করে যদি না আপনি fields
প্যারামিটার ব্যবহার করে ডেটার পরিমাণ কমাতে ব্যবহার করেন।
যদি একটি প্যাচ অনুরোধ একটি নতুন রিসোর্স স্থিতিতে পরিণত হয় যা সিনট্যাক্টিক্যাল বা শব্দার্থগতভাবে অবৈধ, সার্ভারটি একটি 400 Bad Request
বা 422 Unprocessable Entity
HTTP স্ট্যাটাস কোড ফেরত দেয় এবং রিসোর্স অবস্থা অপরিবর্তিত থাকে। উদাহরণস্বরূপ, যদি আপনি একটি প্রয়োজনীয় ক্ষেত্রের জন্য মান মুছে ফেলার চেষ্টা করেন, সার্ভার একটি ত্রুটি প্রদান করে।
প্যাচ HTTP ক্রিয়া সমর্থিত না হলে বিকল্প স্বরলিপি
যদি আপনার ফায়ারওয়াল HTTP PATCH
অনুরোধের অনুমতি না দেয়, তাহলে একটি HTTP POST
অনুরোধ করুন এবং ওভাররাইড হেডারটিকে PATCH
এ সেট করুন, যেমনটি নীচে দেখানো হয়েছে:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
প্যাচ এবং আপডেটের মধ্যে পার্থক্য
অনুশীলনে, আপনি যখন HTTP PUT
ক্রিয়া ব্যবহার করে এমন একটি আপডেট অনুরোধের জন্য ডেটা পাঠান, তখন আপনাকে শুধুমাত্র সেই ক্ষেত্রগুলি পাঠাতে হবে যেগুলি হয় প্রয়োজন বা ঐচ্ছিক; আপনি যদি সার্ভার দ্বারা সেট করা ক্ষেত্রগুলির জন্য মান পাঠান, সেগুলি উপেক্ষা করা হয়। যদিও এটি আংশিক আপডেট করার অন্য উপায় বলে মনে হতে পারে, এই পদ্ধতির কিছু সীমাবদ্ধতা রয়েছে। HTTP PUT
ক্রিয়া ব্যবহার করে এমন আপডেটগুলির সাথে, আপনি প্রয়োজনীয় প্যারামিটার সরবরাহ না করলে অনুরোধটি ব্যর্থ হয় এবং আপনি যদি ঐচ্ছিক পরামিতি সরবরাহ না করেন তবে এটি পূর্বে সেট করা ডেটা সাফ করে।
এই কারণে প্যাচ ব্যবহার করা অনেক নিরাপদ। আপনি শুধুমাত্র যে ক্ষেত্রগুলি পরিবর্তন করতে চান তার জন্য ডেটা সরবরাহ করুন; আপনি বাদ দেওয়া ক্ষেত্রগুলি সাফ করা হয় না। এই নিয়মের একমাত্র ব্যতিক্রমটি পুনরাবৃত্তি করা উপাদান বা অ্যারেগুলির সাথে ঘটে: আপনি যদি তাদের সবগুলি বাদ দেন তবে তারা যেমন আছে ঠিক তেমনই থাকবে; আপনি যদি তাদের কোনোটি প্রদান করেন, তাহলে পুরো সেটটি আপনার দেওয়া সেট দিয়ে প্রতিস্থাপিত হবে।
Google Wallet এ ব্যাচের অনুরোধ
Google Wallet API একটি ক্লায়েন্টের সংযোগের সংখ্যা কমাতে একসাথে API কলগুলি ব্যাচিং সমর্থন করে৷ ব্যাচ অনুরোধ এবং প্রতিক্রিয়া গঠন সম্পর্কে আরও তথ্যের জন্য, ব্যাচের বিবরণ দেখুন।
নিম্নলিখিত নমুনা কোড ব্যাচিং অনুরোধ প্রদর্শন করে। জাভা এবং পিএইচপি উদাহরণগুলি ক্লাস এবং অবজেক্ট তৈরিকে সহজ করতে Google Wallet লাইব্রেরি ব্যবহার করে।
জাভা
জাভাতে আপনার ইন্টিগ্রেশন শুরু করতে, 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<LoyaltyObject> callback = new JsonBatchCallback<LoyaltyObject>() { // Invoked if the request was successful public void onSuccess(LoyaltyObject 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/retail/loyalty-cards/rest/v1/loyaltyobject LoyaltyObject batchObject = new LoyaltyObject() .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))) .setAccountId("Account ID") .setAccountName("Account name") .setLoyaltyPoints( new LoyaltyPoints() .setLabel("Points") .setBalance(new LoyaltyPointsBalance().setInt(800))); service.loyaltyobject().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/retail/loyalty-cards/rest/v1/loyaltyobject $batchObject = new LoyaltyObject([ '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 ]) ], 'accountId' => 'Account ID', 'accountName' => 'Account name', 'loyaltyPoints' => new LoyaltyPoints([ 'balance' => new LoyaltyPointsBalance([ 'int' => 800 ]) ]) ]); $batch->add($this->service->loyaltyobject->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/retail/loyalty-cards/rest/v1/loyaltyobject 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 }], 'accountId': 'Account id', 'accountName': 'Account name', 'loyaltyPoints': { 'label': 'Points', 'balance': { 'int': 800 } } } batch.add(self.client.loyaltyobject().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/retail/loyalty-cards/rest/v1/loyaltyobject LoyaltyObject batchObject = new LoyaltyObject { 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 } }, AccountId = "Account id", AccountName = "Account name", LoyaltyPoints = new LoyaltyPoints { Label = "Points", Balance = new LoyaltyPointsBalance { Int__ = 800 } } }; data += "--batch_createobjectbatch\n"; data += "Content-Type: application/json\n\n"; data += "POST /walletobjects/v1/loyaltyObject/\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
নোডে আপনার ইন্টিগ্রেশন শুরু করতে, 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/retail/loyalty-cards/rest/v1/loyaltyobject 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 } ], 'accountId': 'Account id', 'accountName': 'Account name', 'loyaltyPoints': { 'label': 'Points', 'balance': { 'int': 800 } } }; data += '--batch_createobjectbatch\n'; data += 'Content-Type: application/json\n\n'; data += 'POST /walletobjects/v1/loyaltyObject\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 *demoLoyalty) batchCreateObjects(issuerId, classSuffix string) { data := "" for i := 0; i < 3; i++ { objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_") loyaltyObject := new(walletobjects.LoyaltyObject) loyaltyObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) loyaltyObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) loyaltyObject.AccountName = "Account name" loyaltyObject.AccountId = "Account id" loyaltyObject.State = "ACTIVE" loyaltyJson, _ := json.Marshal(loyaltyObject) batchObject := fmt.Sprintf("%s", loyaltyJson) data += "--batch_createobjectbatch\n" data += "Content-Type: application/json\n\n" data += "POST /walletobjects/v1/loyaltyObject\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) } }