أفضل الممارسات حول استخدام خدمات الويب في Route Optimization API

إنّ خدمات الويب على "منصة خرائط Google" عبارة عن مجموعة من واجهات HTTP لخدمات Google التي توفّر بيانات جغرافية لتطبيقات الخرائط.

يوضِّح هذا الدليل بعض الممارسات الشائعة المفيدة لإعداد طلبات خدمات الويب ومعالجة ردود الخدمات. راجِع دليل المطوّر للاطّلاع على المستندات الكاملة حول Route Optimization API.

ما المقصود بخدمة الويب؟

إنّ خدمات الويب على "منصة خرائط Google" هي واجهة لطلب بيانات "واجهة برمجة التطبيقات للخرائط" من الخدمات الخارجية واستخدام البيانات داخل تطبيقات "خرائط Google". تم تصميم هذه الخدمات لاستخدامها مع الخريطة، وفقًا لقيود الترخيص في بنود خدمة "منصة خرائط Google".

تستخدم خدمات الويب لواجهات برمجة التطبيقات لخرائط Google طلبات HTTP(S) لعناوين URL محددة، لتمرير معلمات عناوين URL و/أو بيانات POST بتنسيق JSON كوسيطات للخدمات. بشكل عام، تعرض هذه الخدمات البيانات في نص الاستجابة بتنسيق JSON للتحليل و/أو المعالجة بواسطة تطبيقك.

يوضح المثال التالي عنوان URL لطلب POST REST إلى طريقة optimizeTours:

https://routeoptimization.googleapis.com/v1/projects/PROJECT_NUMBER:optimizeTours

استبدِل PROJECT_NUMBER برقم أو رقم تعريف المشروع على السحابة الإلكترونية الذي تم تفعيل Route Optimization API فيه.

أدرِج رسالة OptimizeToursRequest باعتبارها نص الطلب بتنسيق JSON.

ملاحظة: تتطلب جميع تطبيقات Route Optimization API مصادقة. يمكنك الحصول على مزيد من المعلومات حول بيانات اعتماد المصادقة.

الوصول إلى طبقة المقابس الآمنة/بروتوكول أمان طبقة النقل (TLS)

يكون بروتوكول HTTPS مطلوبًا لجميع طلبات "منصة خرائط Google" التي تستخدم مفاتيح واجهة برمجة التطبيقات أو تحتوي على بيانات المستخدمين. قد يتم رفض الطلبات المقدَّمة عبر HTTP والتي تحتوي على بيانات حسّاسة.

إنشاء عنوان URL صالح

قد تعتقد أن عنوان URL "الصالح" واضح بذاته، ولكن هذا ليس صحيحًا تمامًا. عنوان URL الذي يتم إدخاله في شريط العناوين في أحد المتصفحات مثلاً، قد يحتوي على رموز خاصة (مثل "上海+中國")؛ يحتاج المتصفّح داخليًا إلى ترجمة هذه الأحرف إلى ترميز مختلف قبل النقل. وبالطريقة نفسها، قد يتعامل أي رمز ينشئ إدخال UTF-8 أو يقبله مع عناوين URL التي تتضمن أحرف UTF-8 على أنها "صالحة"، ولكن قد يحتاج أيضًا إلى ترجمة هذه الأحرف قبل إرسالها إلى أحد خوادم الويب. تُسمى هذه العملية ترميز عناوين URL أو الترميز المئوية.

الأحرف الخاصة

نحتاج إلى ترجمة الرموز الخاصة لأنّ جميع عناوين URL يجب أن تتوافق مع البنية المحدّدة في مواصفات معرّف الموارد المنتظم (URI). ويعني هذا أن عناوين URL يجب أن تحتوي فقط على مجموعة فرعية خاصة من أحرف ASCII: الرموز الأبجدية الرقمية المألوفة وبعض الأحرف المحجوزة لاستخدامها كأحرف تحكم داخل عناوين URL. يلخص هذا الجدول هذه الأحرف:

ملخّص أحرف عناوين URL الصالحة
ضبطالأحرفاستخدام عنوان URL
أحرف أبجدية رقمية أ ب ج د ه ث ح ح ي ي ك l ي ت ف ص ص ص ض ي ف ي س ص ز أ ب ج د ه ي خ خ ط ط ط ط ع ط ظ ع ط ط ظ ع ط ط ظ ع ط ظ السلاسل النصية واستخدام النظام (http) والمنفذ (8080) وغير ذلك
غير محجوز - _ . ~ السلاسل النصية
تم الحجز ! * ' ( ) ; : @ & = + $ , / ؟ % # [ ] أحرف التحكّم و/أو سلاسل النص

عند إنشاء عنوان URL صالح، يجب التأكّد من أنّه لا يتضمّن سوى الأحرف المعروضة في جدول "ملخّص أحرف عناوين URL الصالحة". يؤدي إنشاء عنوان URL لاستخدام هذه المجموعة من الأحرف بشكل عام إلى حدوث مشكلتَين، إحداهما إغفال وواحدة من الاستبدال:

  • توجد الأحرف التي تريد التعامل معها خارج المجموعة أعلاه. على سبيل المثال، يجب ترميز الأحرف في اللغات الأجنبية مثل 上海+中國 باستخدام الأحرف المذكورة أعلاه. وفقًا للاصطلاح الشائع، غالبًا ما يتم تمثيل المسافات (غير المسموح بها ضمن عناوين URL) باستخدام علامة الجمع '+' أيضًا.
  • توجد الأحرف في المجموعة أعلاه كأحرف محجوزة، ولكن يجب استخدامها حرفيًا. على سبيل المثال، يتم استخدام ? ضمن عناوين URL للإشارة إلى بداية سلسلة طلب البحث. وإذا كنت تريد استخدام السلسلة "?" و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 الذي تتلقّاه من البيانات التي يُدخلها المستخدم أمرًا صعبًا أحيانًا. على سبيل المثال، قد يُدخِل المستخدم عنوانًا على النحو التالي: "شارع جامعة الدول العربية". بشكل عام، يجب إنشاء عنوان URL من أجزائه، مع التعامل مع أي إدخال للمستخدم كأحرف حرفية.

بالإضافة إلى ذلك، تقتصر عناوين URL على 16384 حرفًا لجميع خدمات الويب على "منصة خرائط Google" وواجهات برمجة تطبيقات الويب الثابتة. في معظم الخدمات، نادرًا ما يتم الاقتراب من عدد الأحرف المسموح به. مع ذلك، يُرجى العلم بأنّ بعض الخدمات تتضمّن عدة معلَمات قد تؤدي إلى إنشاء عناوين URL طويلة.

استخدام مهذب لواجهات Google APIs

يمكن لبرامج واجهة برمجة التطبيقات ذات التصميم السيئ تحميل حمل زائد أكثر من اللازم على كل من الإنترنت وخوادم Google. يحتوي هذا القسم على بعض أفضل الممارسات لعملاء واجهات برمجة التطبيقات. باتّباع أفضل الممارسات هذه، يمكنك تجنُّب حظر تطبيقك بسبب إساءة الاستخدام غير المقصودة لواجهات برمجة التطبيقات.

تراجع أسي

في بعض الحالات النادرة، قد يحدث خطأ ما أثناء تقديم طلبك، وقد تتلقى رمز استجابة HTTP 4XX أو 5XX أو قد يفشل اتصال بروتوكول التحكم بالنقل في مكان ما بين العميل وخادم Google. غالبًا ما يكون من المفيد إعادة محاولة الطلب لأن طلب المتابعة قد ينجح عندما فشل الطلب الأصلي. ومع ذلك، من المهم عدم تكرار إجراء الطلبات إلى خوادم Google بشكل متكرر. ويمكن أن يؤدي هذا السلوك التكراري إلى تحميل الشبكة بين العميل وGoogle بشكل زائد مما يتسبب في مشاكل للعديد من الأطراف.

أفضل نهج هو إعادة المحاولة مع زيادة التأخيرات بين المحاولات. عادةً ما يزداد التأخير بعامل مضاعف مع كل محاولة، وهو نهج يُعرف باسم التراجع الأسي.

على سبيل المثال، جرّب أحد التطبيقات التي يريد إرسال هذا الطلب إلى Time Zone API:

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

يجب أيضًا الانتباه لعدم توفُّر رمز لإعادة محاولة تنفيذ رمز أعلى في سلسلة استدعاءات التطبيقات تؤدي إلى تكرار الطلبات في تتابع سريع.

الطلبات المتزامنة

قد تبدو الأعداد الكبيرة من الطلبات المتزامنة إلى واجهات برمجة التطبيقات من Google كهجوم لحجب الخدمة الموزع (DDoS) على بنية Google الأساسية وسيتم التعامل معها وفقًا لذلك. لتجنّب ذلك، عليك التأكّد من عدم مزامنة طلبات البيانات من واجهة برمجة التطبيقات بين البرامج.

على سبيل المثال، ضع في الاعتبار تطبيقًا يعرض الوقت في المنطقة الزمنية الحالية. من المحتمل أن يضبط هذا التطبيق منبهًا في نظام تشغيل العميل لإيقاظه في بداية الدقيقة حتى يتم تحديث الوقت المعروض. يجب ألا يُجري التطبيق أي طلبات بيانات من واجهة برمجة التطبيقات كجزء من المعالجة المرتبطة بهذا التنبيه.

يُعدّ إجراء طلبات بيانات من واجهة برمجة التطبيقات استجابةً لأحد المنبّهات الثابتة طريقة سيئة لأنّ ذلك يؤدي إلى مزامنة طلبات البيانات من واجهة برمجة التطبيقات مع بداية الدقيقة، حتى بين الأجهزة المختلفة، بدلاً من توزيعها بالتساوي على مدار الوقت. سينتج عن التطبيق المصمم بشكل سيئ القيام بذلك تكدس بيانات في مستويات عادية ستين مرة في بداية كل دقيقة.

بدلاً من ذلك، فإن أحد التصميمات الجيدة المحتملة هو تعيين تنبيه ثاني على وقت يتم اختياره عشوائيًا. عندما ينشط المنبّه الثاني، يستدعي التطبيق أي واجهات برمجة تطبيقات يحتاج إليها ويخزّن النتائج. عندما يريد التطبيق تحديث عرضه في بداية الدقيقة، فإنه يستخدم النتائج المخزنة مسبقًا بدلاً من استدعاء واجهة برمجة التطبيقات مرة أخرى. باستخدام هذا النهج، يتم توزيع طلبات البيانات من واجهة برمجة التطبيقات بالتساوي على مدار الوقت. علاوة على ذلك، لا تؤخر طلبات البيانات من واجهة برمجة التطبيقات العرض أثناء تحديث الشاشة.

باستثناء بداية الدقيقة، هناك أوقات مزامنة شائعة أخرى يجب عدم استهدافها في بداية الساعة، وأن تبدأ كل يوم في منتصف الليل.

معالجة الردود

ويناقش هذا القسم كيفية استخراج هذه القيم ديناميكيًا من استجابات خدمة الويب.

تقدّم خدمات الويب "خرائط Google" ردودًا يسهل فهمها، ولكنّها ليست سهلة الاستخدام تمامًا. عند إجراء استعلام، بدلاً من عرض مجموعة من البيانات، ربما ترغب في استخراج بعض القيم المحددة. بشكل عام، سترغب في تحليل الردود من خدمة الويب واستخراج القيم التي تهمّك فقط.

يعتمد نظام التحليل الذي تستخدمه على ما إذا كنت تعرض الناتج بتنسيق JSON. يمكن معالجة استجابات JSON التي تكون في شكل كائنات JavaScript داخل JavaScript نفسها على العميل.