أفضل الممارسات باستخدام خدمات ويب الطرق على الويب

خدمات الويب في Google Maps Platform هي مجموعة من واجهات HTTP لخدمات Google، وهي توفر بيانات جغرافية لتطبيقات الخرائط.

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

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

خدمات الويب في Google Maps Platform هي واجهة لطلب بيانات واجهة برمجة تطبيقات الخرائط من خدمات خارجية واستخدام البيانات ضمن تطبيقات الخرائط. تم تصميم هذه الخدمات للاستخدام مع خريطة، وفقًا لقيود الترخيص المُضمنة في بنود خدمة "منصة خرائط Google".

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

يكون طلب خدمة الويب النموذجي لـ Roads API بشكل عام على النحو التالي:

https://roads.googleapis.com/v1/snapToRoads?parameters&key=YOUR_API_KEY

حيث تشير السمة snapToRoads إلى الخدمة المعيّنة المطلوبة. وتشمل خدمات الطرق الأخرى nearestRoads وspeedLimits.

ملاحظة: تتطلب جميع تطبيقات واجهة برمجة التطبيقات للطرق المصادقة. مزيد من المعلومات عن بيانات اعتماد المصادقة

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

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

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

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

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

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

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

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

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

يتم ترميز جميع الأحرف المطلوب ترميزها باستخدام عنوان 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 أو قد يفشل اتصال TCP في مكان ما بين العميل وخادم 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 نفسها على العميل.