পারফর্ম্যান্স সংক্রান্ত পরামর্শ

আপনার অ্যাপ্লিকেশনের পারফর্ম্যান্স উন্নত করতে, এই ডকুমেন্টে কিছু কৌশল সম্পর্কে বলা হয়েছে যা আপনি ব্যবহার করতে পারেন। কিছু ক্ষেত্রে, উপস্থাপিত ধারণাগুলি ব্যাখ্যা করার জন্য অন্যান্য API বা জেনেরিক API থেকে উদাহরণ ব্যবহার করা হয়। তবে, একই ধারণা Google Wallet API-এর ক্ষেত্রেও প্রযোজ্য।

gzip ব্যবহার করে কম্প্রেস করা

প্রতিটি অনুরোধের জন্য প্রয়োজনীয় ব্যান্ডউইথ কমানোর একটি সহজ এবং সুবিধাজনক উপায় হল gzip কম্প্রেশন চালু করা। যদিও এর জন্য ফলাফল আনকমপ্রেস করতে অতিরিক্ত CPU টাইম প্রয়োজন, তবে নেটওয়ার্ক খরচের সাথে ট্রেড-অফ সাধারণত এটিকে খুব মূল্যবান করে তোলে।

gzip-এনকোড করা উত্তর পেতে আপনাকে দুটি কাজ করতে হবে: Accept-Encoding হেডার সেট করুন এবং আপনার ইউজার এজেন্ট পরিবর্তন করুন যাতে gzip স্ট্রিং থাকে। gzip কম্প্রেশন চালু করার জন্য সঠিকভাবে তৈরি করা HTTP হেডারের একটি উদাহরণ এখানে দেওয়া হল:

Accept-Encoding: gzip
User-Agent: my program (gzip)

আংশিক রিসোর্স নিয়ে কাজ করা

আপনার API কলের পারফর্ম্যান্স উন্নত করার আরেকটি উপায় হল, আপনি যে ডেটা দেখতে আগ্রহী শুধুমাত্র সেই ডেটা পাঠানো এবং গ্রহণ করা। এটি আপনার অ্যাপ্লিকেশনকে অপ্রয়োজনীয় ফিল্ড ট্রান্সফার, পার্স ও স্টোর করা থেকে বিরত রাখে, যাতে এটি নেটওয়ার্ক, সিপিইউ ও মেমরি সহ রিসোর্স আরও দক্ষতার সাথে ব্যবহার করতে পারে।

আংশিক অনুরোধ দুই ধরনের হয়:

  • আংশিক উত্তর: এমন একটি অনুরোধ যেখানে আপনি নির্দিষ্ট করেন যে উত্তরে কোন কোন ফিল্ড অন্তর্ভুক্ত করতে হবে (fields অনুরোধ প্যারামিটার ব্যবহার করুন)।
  • প্যাচ: একটি আপডেট অনুরোধ যেখানে আপনি শুধুমাত্র সেইসব ফিল্ড পাঠান যেগুলি আপনি পরিবর্তন করতে চান (PATCH HTTP ভার্ব ব্যবহার করুন)।

আংশিক অনুরোধ করার ব্যাপারে আরও বিবরণ নিম্নলিখিত বিভাগে দেওয়া আছে।

আংশিক উত্তর

ডিফল্ট হিসেবে, অনুরোধ প্রসেস করার পরে সার্ভার রিসোর্সের সম্পূর্ণ উপস্থাপনা ফেরত পাঠায়। আরও ভালো পারফর্ম্যান্সের জন্য, আপনি সার্ভারকে শুধুমাত্র সেইসব ফিল্ড পাঠাতে বলতে পারেন যেগুলি আপনার সত্যিই প্রয়োজন এবং পরিবর্তে আংশিক উত্তর পেতে পারেন।

আংশিক উত্তরের অনুরোধ করতে, আপনি যে ফিল্ড ফেরত চান তা নির্দিষ্ট করতে fields অনুরোধ প্যারামিটার ব্যবহার করুন। যে অনুরোধের উত্তরে ডেটা দেখানো হয়, সেটির সাথে আপনি এই প্যারামিটার ব্যবহার করতে পারবেন।

মনে রাখবেন, fields প্যারামিটার শুধুমাত্র উত্তরের ডেটার উপর প্রভাব ফেলে; আপনাকে কোনও ডেটা পাঠাতে হলে, সেটির উপর কোনও প্রভাব ফেলে না। রিসোর্স পরিবর্তন করার সময় আপনার পাঠানো ডেটার পরিমাণ কমাতে, প্যাচ অনুরোধ ব্যবহার করুন।

উদাহরণ

নিচের উদাহরণে, সাধারণ (কাল্পনিক) "Demo" 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 ব্যবহার করুন; 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 অনুরোধের প্যারামিটার ভ্যালু হল কমা দিয়ে আলাদা করা ফিল্ডের তালিকা এবং প্রতিটি ফিল্ড রেসপন্সের রুটের সাপেক্ষে নির্দিষ্ট করা হয়। তাই, আপনি list অপারেশন করলে, উত্তরে একটি কালেকশন পাওয়া যায় এবং সাধারণত এতে রিসোর্সের একটি অ্যারে থাকে। আপনি যদি এমন কোনও অপারেশন করেন যা একটি রিসোর্স রিটার্ন করে, তাহলে সেই রিসোর্সের সাপেক্ষে ফিল্ড নির্দিষ্ট করা হয়। আপনি বেছে নেওয়া ফিল্ডটি কোনও অ্যারে হলে (বা অ্যারের অংশ হলে), সার্ভার অ্যারের সব এলিমেন্টের বেছে নেওয়া অংশটি রিটার্ন করে।

এখানে সংগ্রহ-লেভেল উদাহরণ দেওয়া হল:
উদাহরণ এফেক্ট
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 OK HTTP স্ট্যাটাস কোড সহ উত্তর দেয় এবং আপডেট করা রিসোর্সের আংশিক উপস্থাপনা:

200 OK
{
  "etag": "newETagString"
  "title": "",                 /* Title is cleared; deleted comment field is missing. */
  "characteristics": {
    "length": "short",
    "level": "10",             /* Value is updated.*/
    "followers": ["Jo" g>"Liz"], /* New follower Liz is present; deleted Will is missing. */
    "accuracy": "high"         /* New characteristic is present. */
  }
}

সরাসরি প্যাচ অনুরোধ তৈরি করা

কিছু প্যাচ অনুরোধের জন্য, আপনাকে আগে থেকে পাওয়া ডেটার উপর ভিত্তি করে সেগুলি তৈরি করতে হবে। যেমন, আপনি যদি কোনও অ্যারেতে কোনও আইটেম যোগ করতে চান এবং বিদ্যমান অ্যারে এলিমেন্টগুলির কোনওটিই হারাতে না চান, তাহলে আপনাকে অবশ্যই প্রথমে বিদ্যমান ডেটা পেতে হবে। একইভাবে, কোনও API যদি ETags ব্যবহার করে, তাহলে রিসোর্স সফলভাবে আপডেট করার জন্য আপনাকে অনুরোধের সাথে আগের ETag ভ্যালু পাঠাতে হবে।

মনে রাখবেন: 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 ব্যবহার করা হলে, সার্ভার প্যাচ অনুরোধ প্রসেস করার পরে ETag ভ্যালু আপডেট করে, ঠিক যেমন এটি PUT-এর সাথে করে।

আপনি যদি 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-এ ব্যাচ অনুরোধ

Google Wallet API, ক্লায়েন্টকে করতে হবে এমন কানেকশনের সংখ্যা কমাতে, একসাথে API কল ব্যাচ করার সুবিধা দেয়। ব্যাচ অনুরোধ ও উত্তরের স্ট্রাকচার সম্পর্কে আরও জানতে, ব্যাচের বিবরণ দেখুন।

নিচের নমুনা কোড থেকে অনুরোধ ব্যাচ করা সম্পর্কে জানতে পারবেন। ক্লাস ও অবজেক্ট তৈরি করার প্রসেস সহজ করতে Java ও PHP উদাহরণে Google Wallet লাইব্রেরি ব্যবহার করা হয়।

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<EventTicketObject> callback =
      new JsonBatchCallback<EventTicketObject>() {
        // Invoked if the request was successful
        public void onSuccess(EventTicketObject response, HttpHeaders responseHeaders) {
          System.out.println("Batch insert response");
          System.out.println(response.toString());
        }

        // Invoked if the request failed
        public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
          System.out.println("Error Message: " + e.getMessage());
        }
      };

  // Example: Generate three new pass objects
  for (int i = 0; i < 3; i++) {
    // Generate a random object suffix
    String objectSuffix = UUID.randomUUID().toString().replaceAll("[^\\w.-]", "_");

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
    EventTicketObject batchObject =
        new EventTicketObject()
            .setId(String.format("%s.%s", issuerId, objectSuffix))
            .setClassId(String.format("%s.%s", issuerId, classSuffix))
            .setState("ACTIVE")
            .setHeroImage(
                new Image()
                    .setSourceUri(
                        new ImageUri()
                            .setUri(
                                "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"))
                    .setContentDescription(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString()
                                    .setLanguage("en-US")
                                    .setValue("Hero image description"))))
            .setTextModulesData(
                    List.of(
                            new TextModuleData()
                                    .setHeader("Text module header")
                                    .setBody("Text module body")
                                    .setId("TEXT_MODULE_ID")))
            .setLinksModuleData(
                new LinksModuleData()
                    .setUris(
                        Arrays.asList(
                            new Uri()
                                .setUri("http://maps.google.com/")
                                .setDescription("Link module URI description")
                                .setId("LINK_MODULE_URI_ID"),
                            new Uri()
                                .setUri("tel:6505555555")
                                .setDescription("Link module tel description")
                                .setId("LINK_MODULE_TEL_ID"))))
            .setImageModulesData(
                    List.of(
                            new ImageModuleData()
                                    .setMainImage(
                                            new Image()
                                                    .setSourceUri(
                                                            new ImageUri()
                                                                    .setUri(
                                                                            "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"))
                                                    .setContentDescription(
                                                            new LocalizedString()
                                                                    .setDefaultValue(
                                                                            new TranslatedString()
                                                                                    .setLanguage("en-US")
                                                                                    .setValue("Image module description"))))
                                    .setId("IMAGE_MODULE_ID")))
            .setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value"))
            .setLocations(
                    List.of(
                            new LatLongPoint()
                                    .setLatitude(37.424015499999996)
                                    .setLongitude(-122.09259560000001)))
            .setSeatInfo(
                new EventSeat()
                    .setSeat(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("42")))
                    .setRow(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("G3")))
                    .setSection(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("5")))
                    .setGate(
                        new LocalizedString()
                            .setDefaultValue(
                                new TranslatedString().setLanguage("en-US").setValue("A"))))
            .setTicketHolderName("Ticket holder name")
            .setTicketNumber("Ticket number");

    service.eventticketobject().insert(batchObject).queue(batch, callback);
  }

  // Invoke the batch API calls
  batch.execute();
}

PHP

PHP-তে ইন্টিগ্রেশন শুরু করতে, আমাদের সম্পূর্ণ GitHub-এ কোড স্যাম্পেল দেখুন।

/**
 * Batch create Google Wallet objects from an existing class.
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $classSuffix Developer-defined unique ID for the pass class.
 */
public function batchCreateObjects(string $issuerId, string $classSuffix)
{
  // Update the client to enable batch requests
  $this->client->setUseBatch(true);
  $batch = $this->service->createBatch();

  // Example: Generate three new pass objects
  for ($i = 0; $i < 3; $i++) {
    // Generate a random object suffix
    $objectSuffix = preg_replace('/[^\w.-]/i', '_', uniqid());

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
    $batchObject = new EventTicketObject([
      'id' => "{$issuerId}.{$objectSuffix}",
      'classId' => "{$issuerId}.{$classSuffix}",
      'state' => 'ACTIVE',
      'heroImage' => new Image([
        'sourceUri' => new ImageUri([
          'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
        ]),
        'contentDescription' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'Hero image description'
          ])
        ])
      ]),
      'textModulesData' => [
        new TextModuleData([
          'header' => 'Text module header',
          'body' => 'Text module body',
          'id' => 'TEXT_MODULE_ID'
        ])
      ],
      'linksModuleData' => new LinksModuleData([
        'uris' => [
          new Uri([
            'uri' => 'http://maps.google.com/',
            'description' => 'Link module URI description',
            'id' => 'LINK_MODULE_URI_ID'
          ]),
          new Uri([
            'uri' => 'tel:6505555555',
            'description' => 'Link module tel description',
            'id' => 'LINK_MODULE_TEL_ID'
          ])
        ]
      ]),
      'imageModulesData' => [
        new ImageModuleData([
          'mainImage' => new Image([
            'sourceUri' => new ImageUri([
              'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
            ]),
            'contentDescription' => new LocalizedString([
              'defaultValue' => new TranslatedString([
                'language' => 'en-US',
                'value' => 'Image module description'
              ])
            ])
          ]),
          'id' => 'IMAGE_MODULE_ID'
        ])
      ],
      'barcode' => new Barcode([
        'type' => 'QR_CODE',
        'value' => 'QR code value'
      ]),
      'locations' => [
        new LatLongPoint([
          'latitude' => 37.424015499999996,
          'longitude' =>  -122.09259560000001
        ])
      ],
      'seatInfo' => new EventSeat([
        'seat' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => '42'
          ])
        ]),
        'row' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'G3'
          ])
        ]),
        'section' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => '5'
          ])
        ]),
        'gate' => new LocalizedString([
          'defaultValue' => new TranslatedString([
            'language' => 'en-US',
            'value' => 'A'
          ])
        ])
      ]),
      'ticketHolderName' => 'Ticket holder name',
      'ticketNumber' => 'Ticket number'
    ]);

    $batch->add($this->service->eventticketobject->insert($batchObject));
  }

  // Make the batch request
  $batchResponse = $batch->execute();

  print "Batch insert response\n";
  foreach ($batchResponse as $key => $value) {
    if ($value instanceof Google_Service_Exception) {
      print_r($value->getErrors());
      continue;
    }
    print "{$value->getId()}\n";
  }
}

Python

Python-এ আপনার ইন্টিগ্রেশন শুরু করতে, আমাদের সম্পূর্ণ GitHub-এ কোড স্যাম্পেল দেখুন।

def batch_create_objects(self, issuer_id: str, class_suffix: str):
    """Batch create Google Wallet objects from an existing class.

    The request body will be a multiline string. See below for information.

    https://cloud.google.com/compute/docs/api/how-tos/batch#example

    Args:
        issuer_id (str): The issuer ID being used for this request.
        class_suffix (str): Developer-defined unique ID for this pass class.
    """
    batch = self.client.new_batch_http_request()

    # Example: Generate three new pass objects
    for _ in range(3):
        # Generate a random object suffix
        object_suffix = str(uuid.uuid4()).replace('[^\\w.-]', '_')

        # See link below for more information on required properties
        # https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
        batch_object = {
            'id': f'{issuer_id}.{object_suffix}',
            'classId': f'{issuer_id}.{class_suffix}',
            'state': 'ACTIVE',
            'heroImage': {
                'sourceUri': {
                    'uri':
                        'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
                },
                'contentDescription': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'Hero image description'
                    }
                }
            },
            'textModulesData': [{
                'header': 'Text module header',
                'body': 'Text module body',
                'id': 'TEXT_MODULE_ID'
            }],
            'linksModuleData': {
                'uris': [{
                    'uri': 'http://maps.google.com/',
                    'description': 'Link module URI description',
                    'id': 'LINK_MODULE_URI_ID'
                }, {
                    'uri': 'tel:6505555555',
                    'description': 'Link module tel description',
                    'id': 'LINK_MODULE_TEL_ID'
                }]
            },
            'imageModulesData': [{
                'mainImage': {
                    'sourceUri': {
                        'uri':
                            'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
                    },
                    'contentDescription': {
                        'defaultValue': {
                            'language': 'en-US',
                            'value': 'Image module description'
                        }
                    }
                },
                'id': 'IMAGE_MODULE_ID'
            }],
            'barcode': {
                'type': 'QR_CODE',
                'value': 'QR code'
            },
            'locations': [{
                'latitude': 37.424015499999996,
                'longitude': -122.09259560000001
            }],
            'seatInfo': {
                'seat': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': '42'
                    }
                },
                'row': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'G3'
                    }
                },
                'section': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': '5'
                    }
                },
                'gate': {
                    'defaultValue': {
                        'language': 'en-US',
                        'value': 'A'
                    }
                }
            },
            'ticketHolderName': 'Ticket holder name',
            'ticketNumber': 'Ticket number'
        }

        batch.add(self.client.eventticketobject().insert(body=batch_object))

    # Invoke the batch API calls
    response = batch.execute()

    print('Batch complete')

C#

C#-এ আপনার ইন্টিগ্রেশন শুরু করতে, আমাদের সম্পূর্ণ GitHub-এ কোড স্যাম্পেল দেখুন।

/// <summary>
/// Batch create Google Wallet objects from an existing class.
/// </summary>
/// <param name="issuerId">The issuer ID being used for this request.</param>
/// <param name="classSuffix">Developer-defined unique ID for this pass class.</param>
public async void BatchCreateObjects(string issuerId, string classSuffix)
{
  // The request body will be a multiline string
  // See below for more information
  // https://cloud.google.com/compute/docs/api/how-tos/batch//example
  string data = "";

  HttpClient httpClient = new HttpClient();
  httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer",
    credentials.GetAccessTokenForRequestAsync().Result
  );

  // Example: Generate three new pass objects
  for (int i = 0; i < 3; i++)
  {
    // Generate a random object suffix
    string objectSuffix = Regex.Replace(Guid.NewGuid().ToString(), "[^\\w.-]", "_");

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
    EventTicketObject batchObject = new EventTicketObject
    {
      Id = $"{issuerId}.{objectSuffix}",
      ClassId = $"{issuerId}.{classSuffix}",
      State = "ACTIVE",
      HeroImage = new Image
      {
        SourceUri = new ImageUri
        {
          Uri = "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
        },
        ContentDescription = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Hero image description"
          }
        }
      },
      TextModulesData = new List<TextModuleData>
      {
        new TextModuleData
        {
          Header = "Text module header",
          Body = "Text module body",
          Id = "TEXT_MODULE_ID"
        }
      },
      LinksModuleData = new LinksModuleData
      {
        Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri>
        {
          new Google.Apis.Walletobjects.v1.Data.Uri
          {
            UriValue = "http://maps.google.com/",
            Description = "Link module URI description",
            Id = "LINK_MODULE_URI_ID"
          },
          new Google.Apis.Walletobjects.v1.Data.Uri
          {
            UriValue = "tel:6505555555",
            Description = "Link module tel description",
            Id = "LINK_MODULE_TEL_ID"
          }
        }
      },
      ImageModulesData = new List<ImageModuleData>
      {
        new ImageModuleData
        {
          MainImage = new Image
          {
            SourceUri = new ImageUri
            {
              Uri = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"
            },
            ContentDescription = new LocalizedString
            {
              DefaultValue = new TranslatedString
              {
                Language = "en-US",
                Value = "Image module description"
              }
            }
          },
          Id = "IMAGE_MODULE_ID"
        }
      },
      Barcode = new Barcode
      {
        Type = "QR_CODE",
        Value = "QR code"
      },
      Locations = new List<LatLongPoint>
      {
        new LatLongPoint
        {
          Latitude = 37.424015499999996,
          Longitude = -122.09259560000001
        }
      },
      SeatInfo = new EventSeat
      {
        Seat = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "42"
          }
        },
        Row = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "G3"
          }
        },
        Section = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "5"
          }
        },
        Gate = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "A"
          }
        }
      },
      TicketHolderName = "Ticket holder name",
      TicketNumber = "Ticket number"
    };

    data += "--batch_createobjectbatch\n";
    data += "Content-Type: application/json\n\n";
    data += "POST /walletobjects/v1/eventTicketObject/\n\n";

    data += JsonConvert.SerializeObject(batchObject) + "\n\n";
  }
  data += "--batch_createobjectbatch--";

  // Invoke the batch API calls
  HttpRequestMessage batchObjectRequest = new HttpRequestMessage(
      HttpMethod.Post,
      "https://walletobjects.googleapis.com/batch");

  batchObjectRequest.Content = new StringContent(data);
  batchObjectRequest.Content.Headers.ContentType = new MediaTypeHeaderValue(
      "multipart/mixed");
  // `boundary` is the delimiter between API calls in the batch request
  batchObjectRequest.Content.Headers.ContentType.Parameters.Add(
      new NameValueHeaderValue("boundary", "batch_createobjectbatch"));

  HttpResponseMessage batchObjectResponse = httpClient.Send(
      batchObjectRequest);

  string batchObjectContent = await batchObjectResponse
      .Content
      .ReadAsStringAsync();

  Console.WriteLine("Batch insert response");
  Console.WriteLine(batchObjectContent);
}

Node.js

Node-এ আপনার ইন্টিগ্রেশন শুরু করতে, আমাদের সম্পূর্ণ GitHub-এ কোড স্যাম্পেল দেখুন।

/**
 * Batch create Google Wallet objects from an existing class.
 *
 * @param {string} issuerId The issuer ID being used for this request.
 * @param {string} classSuffix Developer-defined unique ID for this pass class.
 */
async batchCreateObjects(issuerId, classSuffix) {
  // See below for more information
  // https://cloud.google.com/compute/docs/api/how-tos/batch#example
  let data = '';
  let batchObject;
  let objectSuffix;

  // Example: Generate three new pass objects
  for (let i = 0; i < 3; i++) {
    // Generate a random object suffix
    objectSuffix = uuidv4().replace('[^\w.-]', '_');

    // See link below for more information on required properties
    // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
    batchObject = {
      'id': `${issuerId}.${objectSuffix}`,
      'classId': `${issuerId}.${classSuffix}`,
      'state': 'ACTIVE',
      'heroImage': {
        'sourceUri': {
          'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
        },
        'contentDescription': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'Hero image description'
          }
        }
      },
      'textModulesData': [
        {
          'header': 'Text module header',
          'body': 'Text module body',
          'id': 'TEXT_MODULE_ID'
        }
      ],
      'linksModuleData': {
        'uris': [
          {
            'uri': 'http://maps.google.com/',
            'description': 'Link module URI description',
            'id': 'LINK_MODULE_URI_ID'
          },
          {
            'uri': 'tel:6505555555',
            'description': 'Link module tel description',
            'id': 'LINK_MODULE_TEL_ID'
          }
        ]
      },
      'imageModulesData': [
        {
          'mainImage': {
            'sourceUri': {
              'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
            },
            'contentDescription': {
              'defaultValue': {
                'language': 'en-US',
                'value': 'Image module description'
              }
            }
          },
          'id': 'IMAGE_MODULE_ID'
        }
      ],
      'barcode': {
        'type': 'QR_CODE',
        'value': 'QR code'
      },
      'locations': [
        {
          'latitude': 37.424015499999996,
          'longitude': -122.09259560000001
        }
      ],
      'seatInfo': {
        'seat': {
          'defaultValue': {
            'language': 'en-US',
            'value': '42'
          }
        },
        'row': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'G3'
          }
        },
        'section': {
          'defaultValue': {
            'language': 'en-US',
            'value': '5'
          }
        },
        'gate': {
          'defaultValue': {
            'language': 'en-US',
            'value': 'A'
          }
        },
      },
      'ticketHolderName': 'Ticket holder name',
      'ticketNumber': 'Ticket number'
    };

    data += '--batch_createobjectbatch\n';
    data += 'Content-Type: application/json\n\n';
    data += 'POST /walletobjects/v1/eventTicketObject\n\n';

    data += JSON.stringify(batchObject) + '\n\n';
  }
  data += '--batch_createobjectbatch--';

  // Invoke the batch API calls
  let response = await this.client.context._options.auth.request({
    url: 'https://walletobjects.googleapis.com/batch',
    method: 'POST',
    data: data,
    headers: {
      // `boundary` is the delimiter between API calls in the batch request
      'Content-Type': 'multipart/mixed; boundary=batch_createobjectbatch'
    }
  });

  console.log('Batch insert response');
  console.log(response);
}

খুলুন

Go-তে ইন্টিগ্রেশন শুরু করতে, GitHub-এ আমাদের সম্পূর্ণ কোড স্যাম্পেল দেখুন GitHub-এ কোড স্যাম্পেল।

// Batch create Google Wallet objects from an existing class.
func (d *demoEventticket) batchCreateObjects(issuerId, classSuffix string) {
	data := ""
	for i := 0; i < 3; i++ {
		objectSuffix := strings.ReplaceAll(uuid.New().String(), "-", "_")

		eventticketObject := new(walletobjects.EventTicketObject)
		eventticketObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
		eventticketObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
		eventticketObject.TicketHolderName = "Ticket holder name"
		eventticketObject.TicketNumber = "Ticket number"
		eventticketObject.State = "ACTIVE"

		eventticketJson, _ := json.Marshal(eventticketObject)
		batchObject := fmt.Sprintf("%s", eventticketJson)

		data += "--batch_createobjectbatch\n"
		data += "Content-Type: application/json\n\n"
		data += "POST /walletobjects/v1/eventTicketObject\n\n"
		data += batchObject + "\n\n"
	}
	data += "--batch_createobjectbatch--"

	res, err := d.credentials.Client(oauth2.NoContext).Post("https://walletobjects.googleapis.com/batch", "multipart/mixed; boundary=batch_createobjectbatch", bytes.NewBuffer([]byte(data)))

	if err != nil {
		fmt.Println(err)
	} else {
		b, _ := io.ReadAll(res.Body)
		fmt.Printf("Batch insert response:\n%s\n", b)
	}
}