روال‌های مطلوب استفاده از «خدمات وب Places Aggregate API»

سرویس‌های وب «پلاتفرم Google Maps» مجموعه‌ای از میاناهای HTTP به سرویس‌های Google است که داده‌های جغرافیایی را برای برنامه‌های نقشه شما ارائه می‌دهد.

این راهنما برخی‌از روال‌های رایج را که برای راه‌اندازی درخواست‌های سرویس وب و پردازش پاسخ‌های سرویس مفید هستند شرح می‌دهد. برای دریافت مستندات کامل Places Aggregate API، به راهنمای توسعه‌دهنده مراجعه کنید.

سرویس وب چیست؟

خدمات وب «پلاتفرم Google Maps» میانایی برای درخواست داده‌های Maps API از سرویس‌های خارجی و استفاده از داده‌ها در برنامه‌های Maps شما است. این سرویس‌ها طراحی شده‌اند تا مطابق با محدودیت‌های پروانه در «شرایط خدمات پلاتفرم Google Maps»، همراه با نقشه استفاده شوند.

خدمات وب «میاناهای برنامه‌سازی کاربردی Maps» از درخواست‌های HTTP(S) به نشانی‌های وب خاص استفاده می‌کنند و پارامترهای نشانی وب و/یا داده‌های POST با قالب JSON را به‌عنوان آرگومان به سرویس‌ها ارسال می‌کنند. به‌طورکلی، این سرویس‌ها داده‌ها را در بدنه پاسخ به‌صورت JSON برای تجزیه و/یا پردازش توسط برنامه شما برمی‌گردانند.

مثال زیر نشانی وب درخواست REST GET را نشان می‌دهد:

curl --location 'https://areainsights.googleapis.com/v1:computeInsights' \
--header 'X-Goog-Api-Key: API_KEY' \
--header 'Content-Type: application/json' \
--data '{
  "insights": ["INSIGHT_COUNT", "INSIGHT_PLACES"],
  "filter": {
    "locationFilter": {
      "circle": {
        "latLng": { "latitude": 51.508, "longitude": -0.128},
        "radius": 200
      }
    },
    "typeFilter": { "includedTypes": "restaurant" }
  }
}'

توجه: همه برنامه‌های Places Aggregate API به اصالت‌سنجی نیاز دارند. درباره اعتبارنامه‌های اصالت‌سنجی بیشتر بدانید.

دسترسی SSL/TLS

برای همه درخواست‌های «پلاتفرم Google Maps» که از کلیدهای API استفاده می‌کنند یا حاوی داده‌های کاربر هستند، HTTPS الزامی است. درخواست‌هایی که ازطریق HTTP ارسال می‌شوند و حاوی داده‌های حساس هستند ممکن است رد شوند.

درحال ساختن نشانی وب معتبر

ممکن است فکر کنید که نشانی وب «معتبر» واضح است، اما این‌طور نیست. نشانی وبی که در نوار نشانی مرورگر وارد می‌شود، برای مثال، ممکن است نویسه‌های خاصی داشته باشد (مثلاً "上海+中國")؛ مرورگر باید قبل‌از انتقال، این نویسه‌ها را به‌صورت داخلی به کدبندی دیگری ترجمه کند. به‌همین ترتیب، هر کدی که ورودی UTF-8 تولید یا دریافت می‌کند ممکن است نشانی‌های وب دارای نویسه‌های UTF-8 را «معتبر» درنظر بگیرد، اما همچنین باید این نویسه‌ها را قبل‌از ارسال به سرور وب ترجمه کند. به این فرایند کدبندی نشانی وب یا کدبندی درصدی می‌گویند.

نویسه‌های خاص

باید نویسه‌های خاص را ترجمه کنیم زیرا همه نشانی‌های وب باید با نحو مشخص‌شده در مشخصات شناسه منبع یکسان (URI) مطابقت داشته باشند. در عمل، این یعنی نشانی‌های وب باید فقط شامل زیرمجموعه خاصی از نویسه‌های ASCII باشد: نمادهای آشنای الفبایی-عددی، و برخی‌از نویسه‌های رزروشده برای استفاده به‌عنوان نویسه‌های کنترلی در نشانی‌های وب. این جدول این نویسه‌ها را خلاصه می‌کند:

خلاصه نویسه‌های نشانی وب معتبر
به‌صفنویسه‌هااستفاده از نشانی وب
الفباعددی a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 رشته‌های نوشتاری، استفاده از طرح (http)، درگاه (8080)، و غیره.
رزرو نشده - _ . ~ رشته‌های نوشتاری
رزروشده ! * ' ( ) ; : @ & = + $ , / ? ‫% # [ ] نویسه‌های کنترلی و/یا رشته‌های نوشتاری

هنگام ساختن نشانی وب معتبر، باید مطمئن شوید که فقط حاوی نویسه‌های نشان‌داده‌شده در جدول باشد. مطابقت دادن نشانی وب برای استفاده از این مجموعه نویسه‌ها معمولاً به دو مشکل منجر می‌شود، یکی حذف و دیگری جایگزینی:

  • نویسه‌هایی که می‌خواهید مدیریت کنید خارج از مجموعه بالا قرار دارند. برای مثال، نویسه‌های زبان‌های خارجی مانند 上海+中國 باید بااستفاده از نویسه‌های بالا کدبندی شوند. طبق قرارداد رایج، فاصله‌ها (که در نشانی‌های وب مجاز نیستند) اغلب بااستفاده از نویسه به‌علاوه '+' نیز نشان داده می‌شوند.
  • نویسه‌ها در مجموعه بالا به‌عنوان نویسه‌های رزروشده وجود دارند، اما باید به‌صورت واقعی استفاده شوند. برای مثال، ? در نشانی‌های وب برای نشان دادن شروع رشته پُرسمان استفاده می‌شود؛ اگر می‌خواهید از رشته «؟ و Mysterions» استفاده کنید، باید نویسه '?' را کدبندی کنید.

همه نویسه‌هایی که باید کدبندی URL شوند بااستفاده از نویسه '%' و مقدار هگز دو نویسه‌ای متناظر با نویسه UTF-8 آن‌ها کدبندی می‌شوند. برای مثال، 上海+中國 در UTF-8 به‌صورت %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B کدبندی نشانی وب می‌شود. رشته ? and the Mysterians به‌صورت %3F+and+the+Mysterians یا %3F%20and%20the%20Mysterians کدبندی نشانی وب می‌شود.

نویسه‌های رایجی که نیاز به کدبندی دارند

برخی‌از نویسه‌های رایجی که باید کدگذاری شوند عبارت‌اند از:

نویسه ناامن مقدار کدبندی‌شده
فاصله %20
» %22
< %3C
> %3E
# %23
٪ %25
| %7C

تبدیل نشانی وبی که از درونداد کاربر دریافت می‌کنید گاهی اوقات دشوار است. برای مثال، کاربر ممکن است نشانی را به‌صورت «5th&Main St.» وارد کند. به‌طورکلی، باید نشانی وب خود را از بخش‌های آن بسازید و هر ورودی کاربر را به‌عنوان نویسه‌های تحت‌اللفظی درنظر بگیرید.

علاوه‌براین، نشانی‌های وب برای همه سرویس‌های وب «پلاتفرم Google Maps» و «میاناهای برنامه‌سازی کاربردی وب» ایستا به ۱۶۳۸۴ نویسه محدود شده است. برای اکثر سرویس‌ها، این حد نویسه به‌ندرت نزدیک می‌شود. بااین‌حال، توجه داشته باشید که برخی‌از سرویس‌ها چندین پارامتر دارند که ممکن است منجر به نشانی‌های وب طولانی شود.

استفاده مؤدبانه از Google APIs

کارخواه‌های میانای برنامه‌سازی کاربردی که طراحی ضعیفی دارند می‌توانند بار بیشتری از حد لازم بر اینترنت و سرورهای Google تحمیل کنند. این بخش شامل برخی‌از روال‌های مطلوب برای مشتریان میاناهای برنامه‌سازی کاربردی است. دنبال کردن این روال‌های مطلوب می‌تواند به شما کمک کند تا از مسدود شدن برنامه‌تان به‌دلیل سوءاستفاده ناخواسته از APIها جلوگیری کنید.

عقب‌نشینی نمایی

در موارد نادر، ممکن است مشکلی در ارائه درخواست شما پیش بیاید؛ ممکن است کد پاسخ HTTP‏ 4XX یا 5XX دریافت کنید، یا اتصال TCP ممکن است به‌سادگی در جایی بین کلاینت شما و سرور Google قطع شود. اغلب ارزش دارد که درخواست را دوباره امتحان کنید زیرا درخواست پیگیری ممکن است درحالی‌که درخواست اصلی ناموفق بوده است موفق شود. بااین‌حال، مهم است که به‌سادگی در یک حلقه تکراری درخواست‌های مکرر به سرورهای Google ارسال نکنید. این رفتار حلقه‌ای می‌تواند شبکه بین مشتری و Google را بیش‌ازحد بار کند و برای بسیاری از طرف‌ها مشکل ایجاد کند.

رویکرد بهتر این است که با افزایش تأخیر بین تلاش‌ها، دوباره امتحان کنید. معمولاً تأخیر با هر تلاش با ضریب ضرب افزایش می‌یابد، رویکردی که به‌عنوان عقب‌گرد نمایی شناخته می‌شود.

برای مثال، برنامه‌ای را درنظر بگیرید که می‌خواهد این درخواست را به «میانای برنامه‌سازی کاربردی منطقه زمانی» ارسال کند:

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

مثال Python زیر نشان می‌دهد که چگونه درخواست را با عقب‌نشینی نمایی انجام دهید:

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}")

همچنین باید مراقب باشید که کد تکرار مجدد در زنجیره فراخوانی برنامه بالاتر نباشد، زیرا این امر منجر به درخواست‌های مکرر در توالی سریع می‌شود.

درخواست‌های همگام‌سازی‌شده

تعداد زیاد درخواست‌های همگام‌سازی‌شده به «میاناهای برنامه‌سازی کاربردی Google» می‌تواند شبیه حمله «انکار سرویس توزیع‌شده» (DDoS) به زیرساخت Google باشد و براساس آن رفتار شود. برای اجتناب از این مشکل، باید مطمئن شوید که درخواست‌های API بین کارخواه‌ها همگام‌سازی نشده‌اند.

برای مثال، برنامه‌ای را درنظر بگیرید که زمان را در منطقه زمانی فعلی نمایش می‌دهد. این برنامه احتمالاً زنگ هشداری در سیستم‌عامل کارخواه تنظیم می‌کند که آن را در ابتدای دقیقه بیدار می‌کند تا زمان نمایش‌داده‌شده به‌روز شود. برنامه نباید هیچ‌گونه فراخوانی میانای برنامه‌سازی کاربردی را به‌عنوان بخشی از پردازش مرتبط با آن هشدار انجام دهد.

برقراری تماس‌های API در پاسخ به زنگ هشدار ثابت خوب نیست زیرا باعث می‌شود تماس‌های API با شروع دقیقه همگام‌سازی شوند، حتی بین دستگاه‌های مختلف، به‌جای اینکه به‌طور یکنواخت درطول زمان توزیع شوند. برنامه‌ای که طراحی ضعیفی دارد و این کار را انجام می‌دهد، در ابتدای هر دقیقه، ترافیکی ۶۰ برابر سطح عادی ایجاد می‌کند.

درعوض، یکی از طراحی‌های خوب ممکن است این باشد که زنگ هشدار دومی را برای زمان تصادفی تنظیم کنید. وقتی این زنگ دوم به‌صدا درمی‌آید، برنامه هر میانای برنامه‌سازی کاربردی را که نیاز دارد فراخوانی می‌کند و نتایج را ذخیره می‌کند. وقتی برنامه می‌خواهد نمایش خود را در ابتدای دقیقه به‌روز کند، از نتایج ذخیره‌شده قبلی استفاده می‌کند و دوباره API را فراخوانی نمی‌کند. با این رویکرد، تماس‌های میانای برنامه‌سازی کاربردی به‌طور یکنواخت درطول زمان توزیع می‌شوند. علاوه‌براین، فراخوان‌های API هنگام به‌روزرسانی نمایشگر، پردازش را به‌تأخیر نمی‌اندازند.

به‌غیراز ابتدای دقیقه، زمان‌های همگام‌سازی رایج دیگری که باید مراقب باشید هدف‌یابی نکنید ابتدای ساعت و ابتدای هر روز در نیمه‌شب است.

درحال پردازش پاسخ‌ها

این بخش درباره نحوه استخراج پویا این مقادیر از پاسخ‌های سرویس وب بحث می‌کند.

خدمات وب Google Maps پاسخ‌هایی ارائه می‌دهد که درک آن‌ها آسان است، اما دقیقاً کاربرپسند نیستند. هنگام اجرای پُرسمان، به‌جای نمایش مجموعه‌ای از داده‌ها، احتمالاً می‌خواهید چند مقدار خاص را استخراج کنید. به‌طورکلی، می‌خواهید پاسخ‌های سرویس وب را تجزیه کنید و فقط مقادیر موردعلاقه‌تان را استخراج کنید.

طرح تجزیه‌ای که استفاده می‌کنید بستگی به این دارد که آیا برونداد را در JSON برمی‌گردانید یا نه. پاسخ‌های JSON که ازقبل در قالب اشیاء جاوا اسکریپت هستند، ممکن است در خود جاوا اسکریپت در سمت مشتری پردازش شوند.