แนวทางปฏิบัติแนะนำในการใช้เว็บเซอร์วิส Map Management API

บริการบนเว็บของ Google Maps Platform คือชุดอินเทอร์เฟซ HTTP สำหรับบริการของ Google ซึ่งให้ข้อมูลทางภูมิศาสตร์สำหรับแอปพลิเคชันแผนที่ของคุณ

คู่มือนี้อธิบายแนวทางปฏิบัติทั่วไปบางอย่างที่เป็นประโยชน์ในการตั้งค่า บริการเว็บ คำขอและการประมวลผลการตอบกลับของบริการ โปรดดูเอกสารประกอบทั้งหมดของ Map Management API ในคู่มือสำหรับนักพัฒนาซอฟต์แวร์

เว็บเซอร์วิสคืออะไร

บริการเว็บของ Google Maps Platform เป็นอินเทอร์เฟซสำหรับขอข้อมูล Maps API จาก บริการภายนอกและใช้ข้อมูลภายในแอปพลิเคชัน Maps บริการเหล่านี้ออกแบบมาเพื่อใช้ร่วมกับแผนที่ตามข้อจำกัดด้านใบอนุญาตในข้อกำหนดในการให้บริการของ Google Maps Platform

บริการบนเว็บของ Maps API ใช้คำขอ HTTP(S) ไปยัง URL ที่เฉพาะเจาะจง โดยส่งพารามิเตอร์ URL และ/หรือข้อมูล POST ในรูปแบบ JSON เป็นอาร์กิวเมนต์ไปยังบริการ โดยทั่วไปแล้ว บริการเหล่านี้จะแสดงข้อมูลใน ส่วนเนื้อหาการตอบกลับเป็น JSON เพื่อให้แอปพลิเคชันของคุณ แยกวิเคราะห์และ/หรือประมวลผลได้

ตัวอย่างต่อไปนี้แสดงคำขอ REST GET ไปยังเมธอด list Map Configs

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

โปรดระบุโทเค็น OAuth ในคำขอAuthorization header ของคำขอ

การเข้าถึง SSL/TLS

ต้องใช้ HTTPS สำหรับคำขอทั้งหมดของ Google Maps Platform ที่ใช้คีย์ API หรือมีข้อมูลผู้ใช้ คำขอที่ส่งผ่าน HTTP ซึ่งมีข้อมูลที่ละเอียดอ่อนอาจถูกปฏิเสธ

การสร้าง URL ที่ถูกต้อง

คุณอาจคิดว่า URL ที่ "ถูกต้อง" นั้นชัดเจนในตัวอยู่แล้ว แต่ ในความเป็นจริงแล้วไม่ใช่ ตัวอย่างเช่น URL ที่ป้อนในแถบที่อยู่ของเบราว์เซอร์อาจมีอักขระพิเศษ (เช่น "上海+中國") เบราว์เซอร์ต้องแปลอักขระเหล่านั้นเป็นการเข้ารหัสอื่นภายในก่อนที่จะส่ง ในทำนองเดียวกัน โค้ดใดๆ ที่สร้างหรือยอมรับอินพุต UTF-8 อาจถือว่า URL ที่มีอักขระ UTF-8 เป็น "ใช้ได้" แต่ก็จะต้อง แปลอักขระเหล่านั้นก่อนที่จะส่งไปยังเว็บเซิร์ฟเวอร์ด้วย กระบวนการนี้เรียกว่า URL-encoding หรือ percent-encoding

อักขระพิเศษ

เราต้องแปลอักขระพิเศษเนื่องจาก URL ทั้งหมดต้องเป็นไปตามไวยากรณ์ที่ระบุโดยข้อกำหนดของตัวระบุทรัพยากรแบบสม่ำเสมอ (URI) ซึ่งหมายความว่า URL ต้องมีเฉพาะอักขระ ASCII ที่เป็นเซ็ตย่อยพิเศษ ได้แก่ สัญลักษณ์ตัวอักษรและตัวเลขที่คุ้นเคย และอักขระที่สงวนไว้บางตัวสำหรับใช้เป็นอักขระควบคุม ภายใน URL ตารางนี้สรุปอักขระดังกล่าว

สรุปอักขระที่ใช้ได้ใน URL
ตั้งค่าอักขระการใช้งาน URL
ตัวอักษรและตัวเลขคละกัน ก ข ค ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ พ ภ ม ย ร ล ว ศ ษ ส ห ฬ อ ฮ อ 0 1 2 3 4 5 6 7 8 9 สตริงข้อความ การใช้รูปแบบ (http) พอร์ต (8080) ฯลฯ
ไม่ได้จอง - _ . ~ สตริงข้อความ
จองแล้ว ! * ' ( ) ; : @ & = + $ , / ? % # [ ] อักขระควบคุมและ/หรือสตริงข้อความ

เมื่อสร้าง URL ที่ถูกต้อง คุณต้องตรวจสอบว่า URL นั้นมีเฉพาะอักขระที่แสดงในตาราง เท่านั้น การปรับ URL ให้ใช้ชุดอักขระนี้มักจะ ทำให้เกิดปัญหา 2 อย่าง ได้แก่ ปัญหาการละเว้นและปัญหาการแทนที่

  • อักขระที่คุณต้องการจัดการอยู่นอกชุดอักขระ ที่ระบุไว้ข้างต้น เช่น อักขระในภาษาต่างประเทศ เช่น 上海+中國 ต้องได้รับการเข้ารหัสโดยใช้อักขระ ด้านบน ตามธรรมเนียมที่นิยมใช้กัน ช่องว่าง (ซึ่งไม่อนุญาตให้ใช้ภายใน URL) มักจะแสดงโดยใช้อักขระบวก '+' ด้วย
  • อักขระจะอยู่ในชุดด้านบนเป็นอักขระที่สงวนไว้ แต่ต้องใช้ตามตัวอักษร เช่น ? ใช้ภายใน URL เพื่อระบุจุดเริ่มต้นของสตริงคำค้นหา หากต้องการใช้สตริง "? and the Mysterions" คุณจะต้องเข้ารหัสอักขระ '?'

อักขระทั้งหมดที่จะเข้ารหัส URL จะได้รับการเข้ารหัส โดยใช้'%'และค่าฐานสิบหก 2 อักขระ ที่สอดคล้องกับอักขระ 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

อักขระทั่วไปที่ต้องเข้ารหัส

อักขระทั่วไปบางส่วนที่ต้องเข้ารหัสมีดังนี้

อักขระที่ไม่ปลอดภัย ค่าที่เข้ารหัส
Space %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

บางครั้งการแปลง URL ที่คุณได้รับจากข้อมูลจากผู้ใช้อาจเป็นเรื่องยาก เช่น ผู้ใช้อาจป้อนที่อยู่เป็น "5th&Main St." โดยทั่วไป คุณควรสร้าง URL จากส่วนต่างๆ โดยถือว่าข้อมูลจากผู้ใช้เป็นอักขระตามตัว

นอกจากนี้ URL ยังมีความยาวไม่เกิน 16384 ตัวสำหรับเว็บเซอร์วิสทั้งหมดของ Google Maps Platform และเว็บ API แบบคงที่ สำหรับบริการส่วนใหญ่ คุณแทบจะไม่ต้องกังวลเรื่องจำนวนอักขระสูงสุดนี้ อย่างไรก็ตาม โปรดทราบว่าบริการบางอย่างมีพารามิเตอร์หลายรายการที่อาจทำให้ URL ยาว

การใช้ Google APIs อย่างสุภาพ

ไคลเอ็นต์ API ที่ออกแบบมาไม่ดีอาจทำให้เกิดโหลดมากกว่าที่จำเป็นทั้งบนอินเทอร์เน็ตและเซิร์ฟเวอร์ของ Google ส่วนนี้มีแนวทางปฏิบัติแนะนำบางส่วนสำหรับไคลเอ็นต์ของ API การปฏิบัติตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้คุณหลีกเลี่ยงไม่ให้แอปพลิเคชันถูกบล็อกเนื่องจากการละเมิด API โดยไม่ตั้งใจได้

Exponential Backoff

ในบางกรณีที่พบไม่บ่อยนัก อาจเกิดข้อผิดพลาดในการแสดงผลคำขอ คุณอาจได้รับโค้ดตอบกลับ HTTP 4XX หรือ 5XX หรือการเชื่อมต่อ TCP อาจล้มเหลวระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ของ Google บ่อยครั้งที่การลองส่งคำขออีกครั้งก็คุ้มค่า เนื่องจากคำขอติดตามอาจสำเร็จเมื่อคำขอเดิมล้มเหลว อย่างไรก็ตาม สิ่งสำคัญคือคุณไม่ควร วนซ้ำเพื่อส่งคำขอไปยังเซิร์ฟเวอร์ของ Google ลักษณะการวนซ้ำนี้อาจทำให้เครือข่ายระหว่างไคลเอ็นต์กับ Google ทำงานหนักเกินไป ซึ่งจะส่งผลให้เกิดปัญหาสำหรับหลายฝ่าย

แนวทางที่ดีกว่าคือการลองอีกครั้งโดยเพิ่มความล่าช้าระหว่างการลองแต่ละครั้ง โดยปกติแล้ว ความล่าช้าจะเพิ่มขึ้นตามปัจจัยคูณในแต่ละครั้ง ซึ่งเป็นแนวทางที่เรียกว่า Exponential Backoff

ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่ต้องการส่งคำขอนี้ไปยัง Time Zone API

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

ตัวอย่าง Python ต่อไปนี้แสดงวิธีส่งคำขอด้วย Exponential Backoff

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

นอกจากนี้ คุณควรระมัดระวังไม่ให้มีโค้ดลองอีกครั้งที่สูงกว่าในห่วงโซ่การเรียกแอปพลิเคชัน ซึ่งนำไปสู่คำขอที่ซ้ำกันอย่างรวดเร็ว

คำขอที่ซิงค์

คำขอจำนวนมากที่ซิงค์กับ API ของ Google อาจดูเหมือนการโจมตีแบบปฏิเสธการให้บริการแบบกระจาย (DDoS) ในโครงสร้างพื้นฐานของ Google และจะได้รับการจัดการตามนั้น หากต้องการหลีกเลี่ยงปัญหานี้ คุณควรตรวจสอบว่าคำขอ API ไม่ได้ซิงค์ข้อมูลระหว่างไคลเอ็นต์

เช่น ลองพิจารณาแอปพลิเคชันที่แสดงเวลาในเขตเวลาปัจจุบัน แอปพลิเคชันนี้อาจตั้งปลุกในระบบปฏิบัติการของไคลเอ็นต์เพื่อปลุกระบบเมื่อเริ่มนาทีเพื่อให้สามารถอัปเดตเวลาที่แสดงได้ แอปพลิเคชันไม่ควรเรียก API ใดๆ เป็นส่วนหนึ่งของการประมวลผลที่เชื่อมโยงกับการเตือนนั้น

การเรียกใช้ API เพื่อตอบสนองต่อการปลุกที่ตั้งเวลาไว้ไม่ดี เนื่องจากจะทำให้การเรียกใช้ API ซิงค์กับการเริ่มต้นของนาที แม้ว่าจะเป็นระหว่างอุปกรณ์ต่างๆ แทนที่จะกระจายอย่างสม่ำเสมอตลอดเวลา แอปพลิเคชันที่ออกแบบมาไม่ดีซึ่งทำเช่นนี้จะทำให้เกิดช่วงที่เพิ่มขึ้นของ การรับส่งข้อมูลที่ระดับปกติ 60 เท่าเมื่อเริ่มต้นในแต่ละนาที

แต่การออกแบบที่ดีอย่างหนึ่งที่เป็นไปได้คือการตั้งปลุกที่ 2 ในเวลาที่สุ่มเลือก เมื่อการปลุกครั้งที่ 2 ทำงาน แอปพลิเคชันจะเรียกใช้ API ที่ต้องการและจัดเก็บผลลัพธ์ เมื่อแอปพลิเคชันต้องการอัปเดตการแสดงผลเมื่อเริ่มต้นนาที แอปพลิเคชันจะใช้ ผลลัพธ์ที่จัดเก็บไว้ก่อนหน้านี้แทนการเรียก API อีกครั้ง เมื่อใช้วิธีนี้ การเรียก API จะกระจายอย่างสม่ำเสมอตลอดระยะเวลา นอกจากนี้ การเรียก API จะไม่ทำให้การแสดงผลล่าช้าเมื่อมีการอัปเดตจอแสดงผล

นอกเหนือจากช่วงต้นนาทีแล้ว เวลาการซิงค์อื่นๆ ที่คุณควรไม่กำหนดเป้าหมายคือช่วงต้นชั่วโมงและช่วงต้นวันตอนเที่ยงคืน

การประมวลผลคำตอบ

ส่วนนี้จะอธิบายวิธีดึงค่าเหล่านี้แบบไดนามิกจากการตอบกลับของเว็บเซอร์วิส

บริการเว็บของ Google Maps ให้การตอบกลับที่เข้าใจง่าย แต่ไม่ค่อยเป็นมิตรกับผู้ใช้ เมื่อทำการค้นหา คุณอาจต้องการดึงค่าที่เฉพาะเจาะจงเพียงไม่กี่ค่าแทนที่จะแสดงชุดข้อมูล โดยทั่วไป คุณจะต้องแยกวิเคราะห์การตอบกลับจากเว็บ เซอร์วิสและดึงเฉพาะค่าที่คุณสนใจ

รูปแบบการแยกวิเคราะห์ที่คุณใช้จะขึ้นอยู่กับว่าคุณจะส่งคืนเอาต์พุตในรูปแบบ JSON หรือไม่ การตอบกลับ JSON ซึ่งอยู่ในรูปแบบของออบเจ็กต์ Javascript อยู่แล้ว อาจได้รับการประมวลผลภายใน Javascript เอง ในไคลเอ็นต์