Các phương pháp hay nhất để sử dụng Dịch vụ web API quản lý bản đồ

Các dịch vụ web của Google Maps Platform là một tập hợp các giao diện HTTP cho các dịch vụ của Google, cung cấp dữ liệu địa lý cho các ứng dụng bản đồ của bạn.

Hướng dẫn này mô tả một số phương pháp phổ biến hữu ích cho việc thiết lập các yêu cầu dịch vụ web và xử lý các phản hồi của dịch vụ. Hãy tham khảo hướng dẫn dành cho nhà phát triển để xem toàn bộ tài liệu về API Quản lý bản đồ.

Dịch vụ web là gì?

Dịch vụ web của Nền tảng Google Maps là một giao diện để yêu cầu dữ liệu API Maps từ các dịch vụ bên ngoài và sử dụng dữ liệu đó trong các ứng dụng Maps của bạn. Các dịch vụ này được thiết kế để sử dụng cùng với bản đồ, theo Các hạn chế về giấy phép trong Điều khoản dịch vụ của Google Maps Platform.

Các dịch vụ web của Maps API sử dụng các yêu cầu HTTP(S) đối với các URL cụ thể, truyền các tham số URL và/hoặc dữ liệu POST ở định dạng JSON làm đối số cho các dịch vụ. Nhìn chung, các dịch vụ này trả về dữ liệu trong phần nội dung phản hồi dưới dạng JSON để ứng dụng của bạn phân tích cú pháp và/hoặc xử lý.

Ví dụ sau đây cho thấy một yêu cầu REST GET đối với phương thức list MapConfigs:

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

Đưa mã thông báo OAuth vào yêu cầu trong Authorization header của yêu cầu.

Quyền truy cập SSL/TLS

Bạn phải sử dụng HTTPS cho tất cả các yêu cầu của Google Maps Platform sử dụng khoá API hoặc chứa dữ liệu người dùng. Các yêu cầu được thực hiện qua HTTP có chứa dữ liệu nhạy cảm có thể bị từ chối.

Tạo URL hợp lệ

Có thể bạn nghĩ rằng một URL "hợp lệ" là điều hiển nhiên, nhưng không hẳn như vậy. Ví dụ: URL được nhập vào thanh địa chỉ trong trình duyệt có thể chứa các ký tự đặc biệt (ví dụ: "上海+中國"); trình duyệt cần dịch nội bộ các ký tự đó thành một phương thức mã hoá khác trước khi truyền. Tương tự, mọi mã tạo hoặc chấp nhận dữ liệu đầu vào UTF-8 đều có thể coi URL có ký tự UTF-8 là "hợp lệ", nhưng cũng cần dịch các ký tự đó trước khi gửi đến một máy chủ web. Quá trình này được gọi là mã hoá URL hoặc mã hoá bằng dấu phần trăm.

Các ký tự đặc biệt

Chúng ta cần dịch các ký tự đặc biệt vì tất cả URL đều phải tuân thủ cú pháp do quy cách Giá trị nhận dạng tài nguyên thống nhất (URI) chỉ định. Trên thực tế, điều này có nghĩa là URL chỉ được chứa một tập hợp con đặc biệt của các ký tự ASCII: các ký hiệu chữ và số quen thuộc và một số ký tự dành riêng để sử dụng làm ký tự điều khiển trong URL. Bảng này tóm tắt các ký tự này:

Tóm tắt các ký tự hợp lệ trong URL
Đặtký tựViệc sử dụng URL
Chữ và số 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 Chuỗi văn bản, cách sử dụng lược đồ (http), cổng (8080), v.v.
Không dành riêng - _ . ~ Chuỗi văn bản
Đã đặt trước ! * ' ( ) ; : @ & = + $ , / ? % # [ ] Ký tự điều khiển và/hoặc Chuỗi văn bản

Khi tạo một URL hợp lệ, bạn phải đảm bảo rằng URL đó chỉ chứa những ký tự xuất hiện trong bảng. Việc điều chỉnh một URL để sử dụng bộ ký tự này thường dẫn đến hai vấn đề, một là bỏ sót và một là thay thế:

  • Các ký tự mà bạn muốn xử lý nằm ngoài bộ ký tự nêu trên. Ví dụ: các ký tự bằng ngôn ngữ nước ngoài (chẳng hạn như 上海+中國) cần được mã hoá bằng các ký tự ở trên. Theo quy ước phổ biến, khoảng trắng (không được phép xuất hiện trong URL) cũng thường được biểu thị bằng ký tự dấu cộng '+'.
  • Các ký tự tồn tại trong bộ ký tự nêu trên dưới dạng ký tự dành riêng, nhưng cần được sử dụng theo đúng nghĩa đen. Ví dụ: ? được dùng trong URL để cho biết phần đầu của chuỗi truy vấn; nếu muốn dùng chuỗi "? and the Mysterions", bạn cần mã hoá ký tự '?'.

Tất cả các ký tự cần được mã hoá URL đều được mã hoá bằng ký tự '%' và giá trị hex gồm 2 ký tự tương ứng với ký tự UTF-8 của chúng. Ví dụ: 上海+中國 trong UTF-8 sẽ được mã hoá thành URL dưới dạng %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. Chuỗi ? and the Mysterians sẽ được mã hoá URL dưới dạng %3F+and+the+Mysterians hoặc %3F%20and%20the%20Mysterians.

Các ký tự phổ biến cần được mã hoá

Sau đây là một số ký tự phổ biến phải được mã hoá:

Ký tự không an toàn Giá trị được mã hoá
Không gian %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

Đôi khi, việc chuyển đổi một URL mà bạn nhận được từ hoạt động đầu vào của người dùng sẽ rất khó khăn. Ví dụ: người dùng có thể nhập địa chỉ là "5th&Main St." Thông thường, bạn nên tạo URL từ các phần của URL đó, coi mọi hoạt động đầu vào của người dùng là ký tự nguyên nghĩa.

Ngoài ra, URL bị giới hạn ở 16384 ký tự đối với tất cả các dịch vụ web và API web tĩnh của Nền tảng Google Maps. Đối với hầu hết các dịch vụ, bạn hiếm khi đạt đến giới hạn ký tự này. Tuy nhiên, xin lưu ý rằng một số dịch vụ có nhiều tham số có thể dẫn đến URL dài.

Sử dụng API của Google một cách lịch sự

Các ứng dụng API được thiết kế kém có thể đặt nhiều tải hơn mức cần thiết trên cả Internet và máy chủ của Google. Phần này trình bày một số phương pháp hay nhất dành cho các ứng dụng sử dụng API. Việc tuân thủ các phương pháp hay nhất này có thể giúp bạn tránh được trường hợp ứng dụng của mình bị chặn do vô tình sử dụng sai mục đích các API.

Thuật toán thời gian đợi luỹ thừa

Trong một số ít trường hợp, có thể xảy ra lỗi khi xử lý yêu cầu của bạn; bạn có thể nhận được mã phản hồi HTTP 4XX hoặc 5XX, hoặc kết nối TCP có thể đơn giản là không thành công ở đâu đó giữa máy khách của bạn và máy chủ của Google. Thường thì bạn nên thử lại yêu cầu vì yêu cầu tiếp theo có thể thành công khi yêu cầu ban đầu không thành công. Tuy nhiên, bạn không nên chỉ lặp lại nhiều lần việc đưa ra yêu cầu đến các máy chủ của Google. Hành vi lặp lại này có thể làm quá tải mạng giữa ứng dụng của bạn và Google, gây ra vấn đề cho nhiều bên.

Cách tốt hơn là thử lại với độ trễ tăng dần giữa các lần thử. Thông thường, độ trễ sẽ tăng theo hệ số nhân với mỗi lần thử, đây là một phương pháp được gọi là Khoảng thời gian đợi tăng theo cấp số nhân.

Ví dụ: hãy xem xét một ứng dụng muốn gửi yêu cầu này đến Time Zone API:

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

Ví dụ sau đây về Python cho thấy cách thực hiện yêu cầu bằng cơ chế lùi luỹ thừa:

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

Bạn cũng nên cẩn thận để không có mã thử lại nào cao hơn trong chuỗi lệnh gọi ứng dụng dẫn đến các yêu cầu lặp lại liên tiếp.

Yêu cầu được đồng bộ hoá

Số lượng lớn các yêu cầu được đồng bộ hoá đến các API của Google có thể trông giống như một cuộc tấn công Từ chối dịch vụ phân tán (DDoS) vào cơ sở hạ tầng của Google và sẽ được xử lý tương ứng. Để tránh trường hợp này, bạn phải đảm bảo rằng các yêu cầu API không được đồng bộ hoá giữa các ứng dụng.

Ví dụ: hãy xem xét một ứng dụng hiển thị thời gian theo múi giờ hiện tại. Ứng dụng này có thể sẽ đặt một báo thức trong hệ điều hành của ứng dụng, đánh thức hệ điều hành đó vào đầu phút để có thể cập nhật thời gian hiển thị. Ứng dụng không được thực hiện bất kỳ lệnh gọi API nào trong quá trình xử lý liên quan đến chuông báo đó.

Việc thực hiện các lệnh gọi API để phản hồi một cảnh báo cố định là không nên vì điều này dẫn đến việc các lệnh gọi API được đồng bộ hoá với thời điểm bắt đầu của phút, ngay cả giữa các thiết bị khác nhau, thay vì được phân phối đồng đều theo thời gian. Một ứng dụng được thiết kế kém sẽ tạo ra mức tăng đột biến về lưu lượng truy cập gấp 60 lần mức bình thường vào đầu mỗi phút.

Thay vào đó, một thiết kế hay có thể là đặt chuông báo thứ hai vào một thời gian được chọn ngẫu nhiên. Khi chuông báo thứ hai này đổ chuông, ứng dụng sẽ gọi mọi API cần thiết và lưu trữ kết quả. Khi muốn cập nhật màn hình hiển thị vào đầu phút, ứng dụng sẽ sử dụng các kết quả đã lưu trữ trước đó thay vì gọi lại API. Với phương pháp này, các lệnh gọi API sẽ được phân bổ đều theo thời gian. Ngoài ra, các lệnh gọi API không làm chậm quá trình kết xuất khi màn hình đang được cập nhật.

Ngoài thời điểm bắt đầu của phút, những thời điểm đồng bộ hoá phổ biến khác mà bạn cần không nhắm đến là thời điểm bắt đầu của một giờ và thời điểm bắt đầu của mỗi ngày vào lúc nửa đêm.

Xử lý câu trả lời

Phần này thảo luận về cách trích xuất các giá trị này một cách linh động từ các phản hồi của dịch vụ web.

Các dịch vụ web của Google Maps cung cấp những phản hồi dễ hiểu nhưng không thực sự thân thiện với người dùng. Khi thực hiện một truy vấn, thay vì hiển thị một tập hợp dữ liệu, có lẽ bạn muốn trích xuất một số giá trị cụ thể. Nhìn chung, bạn sẽ muốn phân tích cú pháp các phản hồi từ dịch vụ web và chỉ trích xuất những giá trị mà bạn quan tâm.

Lược đồ phân tích cú pháp mà bạn sử dụng tuỳ thuộc vào việc bạn có trả về đầu ra ở định dạng JSON hay không. Phản hồi JSON, vốn đã ở dạng đối tượng Javascript, có thể được xử lý trong chính Javascript trên máy khách.