ম্যাপ ম্যানেজমেন্ট API ওয়েব পরিষেবাগুলি ব্যবহার করে সর্বোত্তম অনুশীলন

গুগল ম্যাপস প্ল্যাটফর্ম ওয়েব সার্ভিসগুলো হলো গুগল সার্ভিসগুলোর একগুচ্ছ HTTP ইন্টারফেস, যা আপনার ম্যাপ অ্যাপ্লিকেশনগুলোর জন্য ভৌগোলিক ডেটা সরবরাহ করে।

এই নির্দেশিকাটি আপনার ওয়েব পরিষেবা অনুরোধগুলি সেট আপ করতে এবং পরিষেবা প্রতিক্রিয়াগুলি প্রক্রিয়া করার জন্য দরকারী কিছু সাধারণ পদ্ধতি বর্ণনা করে। ম্যাপ ম্যানেজমেন্ট এপিআই-এর সম্পূর্ণ ডকুমেন্টেশনের জন্য ডেভেলপারের নির্দেশিকা দেখুন।

ওয়েব সার্ভিস বলতে কী বোঝায়?

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

ম্যাপস এপিআই ওয়েব সার্ভিসগুলো নির্দিষ্ট ইউআরএল-এ HTTP(S) রিকোয়েস্ট পাঠায় এবং আর্গুমেন্ট হিসেবে ইউআরএল প্যারামিটার এবং/অথবা JSON-ফরম্যাটের POST ডেটা প্রেরণ করে। সাধারণত, এই সার্ভিসগুলো আপনার অ্যাপ্লিকেশনের পার্সিং এবং/অথবা প্রসেসিংয়ের জন্য রেসপন্স বডিতে JSON ফরম্যাটে ডেটা ফেরত দেয়।

নিম্নলিখিত উদাহরণটি লিস্টের Map Configs মেথডে একটি REST GET অনুরোধ দেখাচ্ছে:

https://mapmanagement.googleapis.com/v2beta/projects/PROJECT_NUMBER_OR_ID/mapConfigs

আপনার অনুরোধের Authorization header একটি OAuth টোকেন অন্তর্ভুক্ত করুন।

SSL/TLS অ্যাক্সেস

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

একটি বৈধ URL তৈরি করা

আপনার মনে হতে পারে যে একটি "বৈধ" ইউআরএল স্বতঃসিদ্ধ, কিন্তু ব্যাপারটা ঠিক তেমন নয়। উদাহরণস্বরূপ, ব্রাউজারের অ্যাড্রেস বারে প্রবেশ করানো একটি ইউআরএল-এ বিশেষ অক্ষর থাকতে পারে (যেমন "上海+中國" ); প্রেরণের আগে ব্রাউজারকে অভ্যন্তরীণভাবে সেই অক্ষরগুলোকে একটি ভিন্ন এনকোডিং-এ অনুবাদ করতে হয়। একইভাবে, যে কোনো কোড যা UTF-8 ইনপুট তৈরি বা গ্রহণ করে, সেটি UTF-8 অক্ষরযুক্ত ইউআরএলগুলোকে "বৈধ" হিসেবে গণ্য করতে পারে, কিন্তু ওয়েব সার্ভারে পাঠানোর আগে সেই অক্ষরগুলোকেও অনুবাদ করার প্রয়োজন হয়। এই প্রক্রিয়াটিকে ইউআরএল-এনকোডিং বা পার্সেন্ট-এনকোডিং বলা হয়।

বিশেষ চরিত্র

আমাদের বিশেষ অক্ষরগুলো অনুবাদ করতে হয়, কারণ সমস্ত URL-কে ইউনিফর্ম রিসোর্স আইডেন্টিফায়ার (URI) স্পেসিফিকেশন দ্বারা নির্দিষ্ট সিনট্যাক্স মেনে চলতে হয়। এর অর্থ হলো, URL-এ অবশ্যই ASCII অক্ষরের একটি বিশেষ উপসেট থাকতে হবে: পরিচিত আলফানিউমেরিক প্রতীকগুলো এবং URL-এর মধ্যে কন্ট্রোল ক্যারেক্টার হিসেবে ব্যবহারের জন্য কিছু সংরক্ষিত অক্ষর। এই সারণিতে এই অক্ষরগুলোর একটি সংক্ষিপ্ত বিবরণ দেওয়া হলো:

বৈধ URL অক্ষরগুলির সারাংশ
সেট চরিত্রগুলি URL ব্যবহার
আলফানিউমেরিক abcdefghijklm nopqrstuvwxyz ABCDEFGHIJKLM NOPQRSTUVWXYZ 0 1 2 3 4 5 6 7 8 9 টেক্সট স্ট্রিং, স্কিম ব্যবহার ( http ), পোর্ট ( 8080 ), ইত্যাদি।
অসংরক্ষিত - _ . ~ টেক্সট স্ট্রিং
সংরক্ষিত ! * ' ( ) ; : @ & = + $ , / ? % # [ ] নিয়ন্ত্রণ অক্ষর এবং/অথবা পাঠ্য স্ট্রিং

একটি বৈধ ইউআরএল তৈরি করার সময়, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে এতে শুধুমাত্র সারণিতে দেখানো অক্ষরগুলোই রয়েছে। এই অক্ষরগুচ্ছ ব্যবহার করার জন্য একটি ইউআরএলকে উপযুক্ত করতে গেলে সাধারণত দুটি সমস্যা দেখা দেয়—একটি হলো অক্ষর বাদ পড়া এবং অন্যটি হলো প্রতিস্থাপন:

  • আপনি যে অক্ষরগুলো পরিচালনা করতে চান, সেগুলো উপরের সেটের বাইরে থাকে। উদাহরণস্বরূপ,上海+中國-এর মতো বিদেশী ভাষার অক্ষরগুলোকে উপরের অক্ষরগুলো ব্যবহার করে এনকোড করতে হয়। প্রচলিত রীতি অনুযায়ী, স্পেস (যা URL-এর মধ্যে অনুমোদিত নয়) প্রায়শই প্লাস '+' চিহ্ন ব্যবহার করে প্রকাশ করা হয়।
  • উপরোক্ত সেটের মধ্যে কিছু অক্ষর সংরক্ষিত অক্ষর হিসেবে বিদ্যমান, কিন্তু সেগুলোকে আক্ষরিকভাবে ব্যবহার করতে হয়। উদাহরণস্বরূপ, URL-এ কোয়েরি স্ট্রিং-এর শুরু বোঝাতে '? ? চিহ্নটি ব্যবহৃত হয়; যদি আপনি "? and the Mysterions" স্ট্রিংটি ব্যবহার করতে চান, তাহলে আপনাকে '?' অক্ষরটি এনকোড করতে হবে।

URL-এনকোড করার জন্য সমস্ত অক্ষরকে একটি '%' অক্ষর এবং তাদের UTF-8 অক্ষরের সাথে সঙ্গতিপূর্ণ একটি দুই-অক্ষরের হেক্স ভ্যালু ব্যবহার করে এনকোড করা হয়। উদাহরণস্বরূপ, UTF-8-এ上海+中國URL-এনকোড করলে হবে %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B? and the Mysterians স্ট্রিংটিকে URL-এনকোড করলে হবে %3F+and+the+Mysterians অথবা %3F%20and%20the%20Mysterians

সাধারণ অক্ষর যেগুলোর এনকোডিং প্রয়োজন

কিছু সাধারণ অক্ষর যা অবশ্যই এনকোড করতে হবে, সেগুলো হলো:

অনিরাপদ চরিত্র এনকোড করা মান
মহাকাশ %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

ব্যবহারকারীর ইনপুট থেকে পাওয়া একটি URL রূপান্তর করা কখনও কখনও বেশ জটিল হতে পারে। উদাহরণস্বরূপ, একজন ব্যবহারকারী "5th&Main St." এর মতো একটি ঠিকানা লিখতে পারেন। সাধারণত, ব্যবহারকারীর দেওয়া যেকোনো ইনপুটকে আক্ষরিক অক্ষর হিসেবে বিবেচনা করে, আপনার URL-টি তার অংশগুলো থেকে তৈরি করা উচিত।

এছাড়াও, গুগল ম্যাপস প্ল্যাটফর্মের সমস্ত ওয়েব সার্ভিস এবং স্ট্যাটিক ওয়েব এপিআই-এর জন্য ইউআরএল ১৬৩৮৪ অক্ষরের মধ্যে সীমাবদ্ধ। বেশিরভাগ সার্ভিসের ক্ষেত্রে, এই অক্ষর সীমা খুব কমই অতিক্রম করা হয়। তবে, মনে রাখবেন যে কিছু নির্দিষ্ট সার্ভিসের বেশ কিছু প্যারামিটার রয়েছে, যার ফলে ইউআরএল দীর্ঘ হতে পারে।

গুগল এপিআই-এর মার্জিত ব্যবহার

ত্রুটিপূর্ণভাবে ডিজাইন করা এপিআই ক্লায়েন্টগুলো ইন্টারনেট এবং গুগলের সার্ভার উভয়ের উপরই প্রয়োজনের চেয়ে বেশি চাপ সৃষ্টি করতে পারে। এই বিভাগে এপিআই ক্লায়েন্টদের জন্য কিছু সর্বোত্তম অনুশীলন উল্লেখ করা হয়েছে। এই সর্বোত্তম অনুশীলনগুলো অনুসরণ করলে, এপিআই-এর অনিচ্ছাকৃত অপব্যবহারের কারণে আপনার অ্যাপ্লিকেশনটি ব্লক হওয়া এড়ানো সম্ভব।

এক্সপোনেনশিয়াল ব্যাকঅফ

বিরল ক্ষেত্রে আপনার অনুরোধটি পূরণ করতে কোনো সমস্যা হতে পারে; আপনি একটি 4XX বা 5XX HTTP রেসপন্স কোড পেতে পারেন, অথবা আপনার ক্লায়েন্ট এবং গুগলের সার্ভারের মধ্যে কোথাও TCP সংযোগটি ব্যর্থ হতে পারে। প্রায়শই অনুরোধটি পুনরায় চেষ্টা করা লাভজনক, কারণ মূল অনুরোধটি ব্যর্থ হলেও পরবর্তী অনুরোধটি সফল হতে পারে। তবে, গুগলের সার্ভারগুলিতে বারবার অনুরোধ পাঠিয়ে একটি চক্র তৈরি না করাটা গুরুত্বপূর্ণ। এই চক্রাকার আচরণ আপনার ক্লায়েন্ট এবং গুগলের মধ্যকার নেটওয়ার্ককে অতিরিক্ত ভারাক্রান্ত করতে পারে, যা অনেক পক্ষের জন্য সমস্যা সৃষ্টি করে।

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

উদাহরণস্বরূপ, এমন একটি অ্যাপ্লিকেশনের কথা ভাবুন যা টাইম জোন এপিআই-এর কাছে এই অনুরোধটি করতে চায়:

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY

নিম্নলিখিত পাইথন উদাহরণটি দেখায় কিভাবে এক্সপোনেনশিয়াল ব্যাকঅফ ব্যবহার করে অনুরোধটি করতে হয়:

import json
import time
import urllib.error
import urllib.parse
import urllib.request

# The maps_key defined below isn't a valid Google Maps API key.
# You need to get your own API key.
# See https://developers.google.com/maps/documentation/timezone/get-api-key
API_KEY = "YOUR_KEY_HERE"
TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json"


def timezone(lat, lng, timestamp):

    # Join the parts of the URL together into one string.
    params = urllib.parse.urlencode(
        {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,}
    )
    url = f"{TIMEZONE_BASE_URL}?{params}"

    current_delay = 0.1  # Set the initial retry delay to 100ms.
    max_delay = 5  # Set the maximum retry delay to 5 seconds.

    while True:
        try:
            # Get the API response.
            response = urllib.request.urlopen(url)
        except urllib.error.URLError:
            pass  # Fall through to the retry loop.
        else:
            # If we didn't get an IOError then parse the result.
            result = json.load(response)

            if result["status"] == "OK":
                return result["timeZoneId"]
            elif result["status"] != "UNKNOWN_ERROR":
                # Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or
                # ZERO_RESULTS. There is no point retrying these requests.
                raise Exception(result["error_message"])

        if current_delay > max_delay:
            raise Exception("Too many retry attempts.")

        print("Waiting", current_delay, "seconds before retrying.")

        time.sleep(current_delay)
        current_delay *= 2  # Increase the delay each time we retry.


if __name__ == "__main__":
    tz = timezone(39.6034810, -119.6822510, 1331161200)
    print(f"Timezone: {tz}")

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

সিঙ্ক্রোনাইজড অনুরোধ

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

উদাহরণস্বরূপ, এমন একটি অ্যাপ্লিকেশনের কথা ভাবুন যা বর্তমান টাইম জোনের সময় প্রদর্শন করে। এই অ্যাপ্লিকেশনটি সম্ভবত ক্লায়েন্ট অপারেটিং সিস্টেমে মিনিটের শুরুতে একটি অ্যালার্ম সেট করবে, যাতে প্রদর্শিত সময় আপডেট করা যায়। সেই অ্যালার্ম সম্পর্কিত প্রক্রিয়াকরণের অংশ হিসেবে অ্যাপ্লিকেশনটির কোনো এপিআই (API) কল করা উচিত নয়

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

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

মিনিটের শুরু ছাড়াও, ঘণ্টার শুরু এবং প্রতিটি দিনের শুরুতে মধ্যরাতের মতো অন্যান্য সাধারণ সিঙ্ক্রোনাইজেশন সময়গুলোকে লক্ষ্য করা থেকে আপনার সতর্ক থাকা উচিত।

প্রতিক্রিয়া প্রক্রিয়াকরণ

এই অংশে আলোচনা করা হয়েছে কিভাবে ওয়েব সার্ভিসের প্রতিক্রিয়া থেকে এই মানগুলি গতিশীলভাবে বের করা যায়।

গুগল ম্যাপস ওয়েব সার্ভিস যে প্রতিক্রিয়া প্রদান করে তা বোঝা সহজ, কিন্তু ঠিক ব্যবহারকারী-বান্ধব নয়। কোনো কোয়েরি চালানোর সময়, একগুচ্ছ ডেটা দেখানোর পরিবর্তে, আপনি সম্ভবত কয়েকটি নির্দিষ্ট মান বের করে আনতে চাইবেন। সাধারণত, আপনি ওয়েব সার্ভিস থেকে প্রাপ্ত প্রতিক্রিয়াগুলো পার্স করে শুধুমাত্র আপনার প্রয়োজনীয় মানগুলোই বের করে আনতে চাইবেন।

আপনি আউটপুট JSON ফরম্যাটে ফেরত দিচ্ছেন কিনা, তার উপর আপনার ব্যবহৃত পার্সিং স্কিমটি নির্ভর করে। JSON রেসপন্সগুলো যেহেতু আগে থেকেই জাভাস্ক্রিপ্ট অবজেক্ট আকারে থাকে, তাই ক্লায়েন্টে সরাসরি জাভাস্ক্রিপ্টের মধ্যেই সেগুলো প্রসেস করা যেতে পারে।