เว็บเซอร์วิสของ Google Maps Platform คือชุดอินเทอร์เฟซ HTTP สำหรับบริการของ Google ที่ให้ข้อมูลทางภูมิศาสตร์สำหรับแอปพลิเคชันแผนที่
คู่มือนี้จะอธิบายแนวทางปฏิบัติทั่วไปที่เป็นประโยชน์ในการตั้งค่าคำขอบริการเว็บและประมวลผลคำตอบของบริการ โปรดดูเอกสารประกอบฉบับเต็มของ Roads API ในคู่มือนักพัฒนาซอฟต์แวร์
เว็บเซอร์วิสคืออะไร
เว็บเซอร์วิสของ Google Maps Platform เป็นอินเทอร์เฟซสำหรับการขอข้อมูล Maps API จากบริการภายนอกและการใช้ข้อมูลภายในแอปพลิเคชัน Maps บริการเหล่านี้ออกแบบมาเพื่อใช้ร่วมกับแผนที่ตามข้อจำกัดของใบอนุญาตในข้อกำหนดในการให้บริการของ Google Maps Platform
บริการบนเว็บของ 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
หมายเหตุ: แอปพลิเคชัน Roads API ทั้งหมดต้องมีการตรวจสอบสิทธิ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลเข้าสู่ระบบสำหรับการตรวจสอบสิทธิ์
การเข้าถึง SSL/TLS
คำขอทั้งหมดของ Google Maps Platform ต้องใช้ HTTPS ซึ่งใช้คีย์ API หรือมีข้อมูลผู้ใช้ คำขอที่ส่งผ่าน HTTP ซึ่งมีข้อมูลที่ละเอียดอ่อนอาจถูกปฏิเสธ
การสร้าง URL ที่ถูกต้อง
คุณอาจคิดว่า URL "ที่ถูกต้อง" นั้นเข้าใจได้ง่ายๆ แต่จริงๆ แล้วไม่ใช่ เช่น URL ที่ป้อนภายในแถบที่อยู่ในเบราว์เซอร์อาจมีอักขระพิเศษ (เช่น "上海+中國"
) เบราว์เซอร์ต้องแปลอักขระเหล่านั้นเป็นการเข้ารหัสรูปแบบอื่นก่อนส่ง
ในทํานองเดียวกัน โค้ดที่สร้างหรือยอมรับอินพุต UTF-8 อาจถือว่า URL ที่มีอักขระ UTF-8 "ถูกต้อง" แต่ก็ต้องแปลอักขระเหล่านั้นก่อนส่งไปยังเว็บเซิร์ฟเวอร์ด้วย
กระบวนการนี้เรียกว่า
การเข้ารหัส URL หรือการเข้ารหัสด้วยเปอร์เซ็นต์
อักขระพิเศษ
เราต้องแปลอักขระพิเศษเนื่องจาก URL ทั้งหมดต้องเป็นไปตามรูปแบบคำสั่งที่ระบุไว้ในข้อกำหนด Uniform Resource Identifier (URI) ซึ่งหมายความว่า URL ต้องมีเฉพาะชุดย่อยพิเศษของอักขระ ASCII ได้แก่ สัญลักษณ์ตัวอักษรและตัวเลขที่คุ้นเคย และอักขระที่สงวนไว้บางตัวเพื่อใช้เป็นอักขระควบคุมภายใน URL ตารางนี้สรุปอักขระเหล่านี้
ตั้งค่า | อักขระ | การใช้งาน URL |
---|---|---|
ตัวอักษรและตัวเลขคละกัน | 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 ) ฯลฯ |
ไม่ได้จอง | - _ . ~ | สตริงข้อความ |
จองแล้ว | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | อักขระควบคุมและ/หรือสตริงข้อความ |
เมื่อสร้าง URL ที่ถูกต้อง คุณต้องตรวจสอบว่า URL ดังกล่าวมีเฉพาะอักขระที่แสดงในตารางเท่านั้น โดยทั่วไป การทำให้ URL ใช้ชุดอักขระนี้ทำให้เกิดปัญหา 2 อย่าง ได้แก่ การละเว้นและการแทนที่
- อักขระที่คุณต้องการจัดการอยู่นอกชุดข้างต้น ตัวอย่างเช่น อักขระในภาษาต่างประเทศ เช่น
上海+中國
ต้องได้รับการเข้ารหัสโดยใช้อักขระข้างต้น ตามธรรมเนียมที่นิยมกัน มักจะใช้อักขระบวก'+'
เพื่อแทนที่เว้นวรรค (ซึ่งไม่อนุญาตใน URL) ด้วย - อักขระที่อยู่ในชุดข้างต้นเป็นอักขระที่สงวนไว้ แต่ต้องใช้ตามตัวอักษร
เช่น
?
ใช้ภายใน URL เพื่อระบุจุดเริ่มต้นของสตริงการค้นหา หากต้องการใช้สตริง "? and the Mysterions" คุณจะต้องเข้ารหัสอักขระ'?'
อักขระทั้งหมดที่จะเข้ารหัส URL จะได้รับการเข้ารหัสโดยใช้อักขระ '%'
และค่าฐาน 16 2 อักขระที่สอดคล้องกับอักขระ UTF-8 ตัวอย่างเช่น 上海+中國
ใน UTF-8 จะเป็น%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B
เมื่อเข้ารหัสเป็น URL สตริง ? 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 ของบริการเว็บและ Web API แบบคงที่ทั้งหมดของ Google Maps Platform จะถูกจำกัดไว้ที่ 16384 อักขระ สำหรับบริการส่วนใหญ่ คุณจะไม่ค่อยถึงขีดจำกัดอักขระนี้ อย่างไรก็ตาม โปรดทราบว่าบริการบางอย่างมีพารามิเตอร์หลายรายการที่อาจส่งผลให้ URL ยาว
การใช้ Google APIs อย่างสุภาพ
ไคลเอ็นต์ API ที่ออกแบบมาไม่ดีอาจทำให้ทั้งอินเทอร์เน็ตและเซิร์ฟเวอร์ของ Google ทำงานหนักเกินความจำเป็น ส่วนนี้มีแนวทางปฏิบัติแนะนำบางส่วนสำหรับไคลเอ็นต์ของ API การปฏิบัติตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้แอปพลิเคชันของคุณไม่ถูกบล็อกเนื่องจากการละเมิด API โดยไม่ได้ตั้งใจ
Exponential Backoff
ในบางกรณีที่พบไม่บ่อยนัก อาจมีบางอย่างผิดพลาดในการส่งคำขอ คุณอาจได้รับโค้ดตอบกลับ HTTP 4XX หรือ 5XX หรือการเชื่อมต่อ TCP อาจไม่สำเร็จระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ของ Google บางครั้งการลองส่งคำขออีกครั้งก็อาจคุ้มค่า เนื่องจากคำขอติดตามผลอาจสำเร็จได้เมื่อคำขอแรกไม่สำเร็จ อย่างไรก็ตาม สิ่งสำคัญคืออย่าทำซ้ำๆ โดยส่งคำขอไปยังเซิร์ฟเวอร์ของ Google ลักษณะการทำงานแบบวนซ้ำนี้อาจทำให้เครือข่ายระหว่างไคลเอ็นต์กับ Google ทำงานหนักเกินไปและก่อให้เกิดปัญหากับหลายฝ่าย
วิธีที่ดีกว่านั้นคือลองอีกครั้งโดยเพิ่มความล่าช้าระหว่างการลอง โดยปกติแล้วความล่าช้าจะเพิ่มขึ้นตามปัจจัยการคูณทุกครั้งที่พยายาม ซึ่งเรียกว่าExponential Backoff
ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่ต้องการให้ส่งคําขอนี้ไปยัง API เขตเวลา
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=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}")
นอกจากนี้ คุณควรตรวจสอบด้วยว่าไม่มีโค้ดลองอีกครั้งที่สูงกว่าในเชนการเรียกแอปพลิเคชัน ซึ่งทําให้เกิดการขอซ้ำหลายครั้งติดต่อกัน
คำขอที่ซิงค์
คำขอที่ซิงค์จำนวนมากไปยัง API ของ Google อาจดูเหมือนการโจมตีแบบปฏิเสธการให้บริการแบบกระจาย (DDoS) โครงสร้างพื้นฐานของ Google และระบบอาจดำเนินการกับคำขอดังกล่าวตามความเหมาะสม หากต้องการหลีกเลี่ยงปัญหานี้ คุณควรตรวจสอบว่าคำขอ API ไม่ได้ซิงค์กันระหว่างไคลเอ็นต์
ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันที่แสดงเวลาในเขตเวลาปัจจุบัน แอปพลิเคชันนี้อาจตั้งปลุกในระบบปฏิบัติการไคลเอ็นต์เพื่อปลุกระบบเมื่อเริ่มนาทีเพื่อให้อัปเดตเวลาที่แสดงได้ แอปพลิเคชันควรไม่เรียก API ใดๆ เป็นส่วนหนึ่งของการประมวลผลที่เกี่ยวข้องกับการแจ้งเตือนนั้น
การเรียก API เพื่อตอบสนองต่อการปลุกแบบคงที่นั้นไม่ดีเนื่องจากจะทำให้การเรียก API ซิงค์กับช่วงเริ่มต้นของนาที แม้จะเป็นระหว่างอุปกรณ์ต่างๆ ก็ตาม แทนที่จะกระจายอย่างสม่ำเสมอเมื่อเวลาผ่านไป แอปพลิเคชันที่ออกแบบมาไม่ดีซึ่งทําเช่นนี้จะทําให้การเข้าชมเพิ่มขึ้นเป็น 60 เท่าของระดับปกติในช่วงเริ่มต้นของแต่ละนาที
แต่การออกแบบที่ดีอย่างหนึ่งอาจเป็นการตั้งปลุกครั้งที่ 2 เป็นเวลาที่เลือกแบบสุ่ม เมื่อการแจ้งเตือนครั้งที่ 2 นี้เริ่มทำงาน แอปพลิเคชันจะเรียกใช้ API ที่จำเป็นและจัดเก็บผลลัพธ์ เมื่อแอปพลิเคชันต้องการอัปเดตการแสดงผลเมื่อเริ่มนาทีใหม่ ก็จะใช้ผลลัพธ์ที่เก็บไว้ก่อนหน้านี้แทนการเรียก API อีกครั้ง เมื่อใช้วิธีนี้ การเรียก API จะกระจายอย่างสม่ำเสมอเมื่อเวลาผ่านไป นอกจากนี้ การเรียก API จะไม่ทำให้การแสดงผลล่าช้าเมื่อมีการอัปเดตจอแสดงผล
นอกจากเวลาเริ่มต้นของนาทีแล้ว ช่วงเวลาอื่นๆ ของการซิงค์ที่พบบ่อยซึ่งคุณควรไม่กำหนดเป้าหมาย ได้แก่ เวลาเริ่มต้นของชั่วโมง และเวลาเริ่มต้นของแต่ละวันตอนเที่ยงคืน
การประมวลผลการตอบกลับ
ส่วนนี้จะอธิบายวิธีดึงค่าเหล่านี้แบบไดนามิกจากการตอบกลับของเว็บเซอร์วิส
เว็บเซอร์วิสของ Google Maps ให้คำตอบที่เข้าใจง่าย แต่ไม่ค่อยเป็นมิตรกับผู้ใช้ เมื่อทำการค้นหา คุณอาจต้องการดึงค่าที่เฉพาะเจาะจง 2-3 ค่าแทนการแสดงชุดข้อมูล โดยทั่วไป คุณจะต้องแยกวิเคราะห์คําตอบจากบริการเว็บและดึงเฉพาะค่าที่คุณสนใจ
รูปแบบการแยกวิเคราะห์ที่คุณใช้จะขึ้นอยู่กับว่าคุณแสดงผลลัพธ์เป็น JSON หรือไม่ การตอบกลับ JSON อยู่ในรูปแบบออบเจ็กต์ JavaScript อยู่แล้ว จึงอาจประมวลผลภายใน JavaScript บนไคลเอ็นต์