Các phương pháp hay nhất khi sử dụng dịch vụ web của API Tối ưu hoá tuyến đường

Các dịch vụ web của Nền tảng Google Maps là một tập hợp các giao diện HTTP gửi tới 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 để 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 tài liệu đầy đủ về API Tối ưu hoá tuyến đường.

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 ứ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 Giới hạn cấp phép trong Điều khoản dịch vụ của Nền tảng Google Maps.

Dịch vụ web của API Maps sử dụng yêu cầu HTTP(S) đến các URL cụ thể, truyền tham số URL và/hoặc dữ liệu POST có định dạng JSON làm đối số cho dịch vụ. Nhìn chung, các dịch vụ này sẽ trả về dữ liệu trong 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 URL của một yêu cầu REST POST đến phương thức optimizeTours:

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

Thay thế PROJECT_NUMBER bằng số hoặc mã của dự án Cloud đã bật API Tối ưu hoá tuyến đường.

Đưa thông báo OptimizeToursRequest của bạn vào dưới dạng nội dung yêu cầu JSON.

Lưu ý: Tất cả ứng dụng API Tối ưu hoá tuyến đường đều yêu cầu xác thực. Tìm hiểu thêm thông tin về thông tin xác thực.

Quyền truy cập SSL/TLS

HTTPS là bắt buộc đối với tất cả các yêu cầu trên Nền tảng Google Maps sử dụng khoá API hoặc chứa dữ liệu người dùng. Các yêu cầu được gửi qua HTTP có chứa dữ liệu nhạy cảm có thể bị từ chối.

Tạo URL hợp lệ

Bạn có thể cho rằng một URL "hợp lệ" là rõ ràng, nhưng điều này không đúng. Ví dụ: một URL được nhập vào thanh địa chỉ của 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ự đó sang một chế độ mã hoá khác trước khi truyền. Tương tự như vậy, mọi mã tạo hoặc chấp nhận dữ liệu đầu vào UTF-8 đều có thể coi các URL có ký tự UTF-8 là "hợp lệ", nhưng cũng cần phải dịch các ký tự đó trước khi gửi đến máy chủ web. Quá trình này được gọi là mã hoá URL hoặc mã hoá phần trăm.

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

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

Tóm tắt các ký tự của URL hợp lệ
Đặtký tựViệc sử dụng URL
Chữ và số a b c d e f g g h i j k l m n o p q r s t t u v w x y z A B C D 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 9 6 7 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 URL đó chỉ chứa các ký tự đó trong bảng Tóm tắt các ký tự của URL hợp lệ. Việc tạo một URL để sử dụng bộ ký tự này thường dẫn đến hai vấn đề, một là bỏ qua và một trong hai trường hợp thay thế:

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

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

Các ký tự phổ biến cần mã hóa

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

Ký tự không an toàn Giá trị được mã hóa
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 là quy trình phức tạp. Ví dụ: người dùng có thể nhập một địa chỉ là "5th&Main St." Nhìn chung, bạn nên tạo URL từ các phần của nó, coi mọi hoạt động đầu vào của người dùng là các ký tự cố định.

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

Sử dụng API của Google lịch sự

Các ứng dụng API được thiết kế kém có thể tạo ra 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 ứng dụng API. Việc làm theo các phương pháp hay nhất này có thể giúp bạn tránh việc ứng dụng bị chặn do vô tình lạm dụng các API này.

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 phân phát 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 có thể kết nối TCP gặp sự cố ở đâu đó giữa ứng dụng khách và máy chủ của Google. Thông thường, 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 trong khi yêu cầu ban đầu không thành công. Tuy nhiên, điều quan trọng là không chỉ liên tục gửi yêu cầu lặp lại đế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 sự cố cho nhiều bên.

Một phương pháp hiệu quả hơn là thử lại và tăng độ trễ giữa các lần thử. Thông thường, độ trễ sẽ được tăng lên theo hệ số nhân sau mỗi lần thử, một phương pháp được gọi là Thời gian đợi luỹ thừa.

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 (API Múi giờ):

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

Ví dụ dùng đoạn mã Python sau cho thấy cách tạo yêu cầu bằng thuật toán thời gian đợ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 thử lại mã 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 đã đồng bộ hoá

Số lượng lớn các yêu cầu đã đồng bộ hoá đối với API của Google có thể giống như một cuộc tấn công Từ chối dịch vụ phân tán (DDoS) nhằm vào cơ sở hạ tầng của Google và được xử lý phù hợp. Để tránh điều 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 chuông báo trong hệ điều hành ứng dụng đánh thức chuông báo vào đầu phút để có thể cập nhật thời gian hiển thị. Ứng dụng không nên 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 lệnh gọi API để phản hồi một chuông báo cố định là không tốt vì điều này dẫn đến việc các lệnh gọi API được đồng bộ hoá đến đầu phút, thậm chí 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 khi thực hiện việc này sẽ khiến lưu lượng truy cập tăng đột biến ở mức 60 lần mức bình thường vào đầu mỗi phút.

Thay vào đó, một cách thiết kế hợp lý có thể là đặt chuông báo thứ hai vào thời điểm được chọn ngẫu nhiên. Khi chuông báo thứ hai này kích hoạt, ứ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 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 được trải đều theo thời gian. Ngoài ra, các lệnh gọi API không trì hoãn việc kết xuất khi màn hình đang được cập nhật.

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

Đang xử lý câu trả lời

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

Các dịch vụ web của Google Maps cung cấp câu trả lời rất 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 truy vấn, thay vì hiển thị một tập dữ liệu, bạn có thể muốn trích xuất một vài giá trị cụ thể. Nhìn chung, bạn nên phân tích cú pháp phản hồi qua dịch vụ web và chỉ trích xuất các giá trị mà bạn quan tâm.

Lược đồ phân tích cú pháp mà bạn sử dụng phụ thuộc vào việc bạn có trả về kết quả trong JSON hay không. Các phản hồi JSON đã ở dạng đối tượng JavaScript có thể được xử lý ngay trong JavaScript trên máy khách.