Roads API 웹 서비스 사용 권장사항

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

Google Maps Platform 웹 서비스는 지도 애플리케이션에 지리 데이터를 제공하는 Google 서비스의 HTTP 인터페이스 모음입니다.

이 가이드에서는 웹 서비스 요청을 설정하고 서비스 응답을 처리하는 데 유용한 몇 가지 일반적인 방법을 설명합니다. Roads API에 대한 전체 문서는 개발자 가이드를 참고하세요.

웹 서비스란 무엇인가요?

Google Maps Platform 웹 서비스는 외부 서비스에 Maps API 데이터를 요청하고 지도 애플리케이션 내에서 데이터를 사용하기 위한 인터페이스입니다. 이러한 서비스는 Google Maps Platform 서비스 약관의 라이선스 제한사항에 따라 지도와 함께 사용하도록 설계되었습니다.

지도 API 웹 서비스는 특정 URL에 대한 HTTP(S) 요청을 사용하여 URL 매개변수 또는 JSON 형식의 POST 데이터를 서비스의 인수로 전달합니다. 일반적으로 이러한 서비스는 애플리케이션의 파싱 또는 처리를 위해 HTTP(S) 요청의 데이터를 JSON으로 반환합니다.

일반적인 Roads API 웹 서비스 요청의 형식은 다음과 같습니다.

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

여기서 snapToRoads는 요청된 특정 서비스를 나타냅니다. 다른 도로 서비스에는 nearestRoadsspeedLimits가 포함됩니다.

참고: 모든 Roads API 애플리케이션에는 인증이 필요합니다. 사용자 인증 정보에 대해 자세히 알아보세요.

SSL/TLS 액세스

API 키를 사용하거나 사용자 데이터를 포함하는 모든 Google Maps Platform 요청에는 HTTPS가 필요합니다. 민감한 정보가 포함된 HTTP를 통한 요청은 거부될 수 있습니다.

올바른 URL 작성

'유효한' URL은 너무나 명확한 것 같지만 실제로는 그렇지 않습니다. 예를 들어 브라우저의 주소 표시줄에 입력된 URL은 특수 문자(예: "上海+中國")를 포함할 수 있고, 이 경우 브라우저는 이러한 문자를 전송하기 전에 내부적으로 다른 인코딩으로 변환해야 합니다. 마찬가지로 UTF-8 입력을 생성하거나 수락하는 코드는 UTF-8 문자가 있는 URL을 '유효한' 것으로 취급할 수 있지만 그러한 문자를 웹 서버로 보내기 전에 변환해야 합니다. 이 과정을 URL 인코딩 또는 퍼센트 인코딩이라고 합니다.

특수문자

모든 URL은 URI(Uniform Resource Identifier) 사양에서 지정된 구문을 준수해야 하므로 특수문자는 변환해야 합니다. 실제로 URL에는 ASCII 문자 중 일부 특수한 문자(예: 익히 알고 있는 영숫자 기호, URL 내에서 제어 문자로 사용하기 위해 예약된 일부 문자)만 포함되어야 합니다. 다음 표에 이러한 문자가 요약되어 있습니다.

올바른 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 3 3 3 텍스트 문자열, 스킴 사용(http), 포트(8080) 등
예약되지 않음 - _ . ~ 텍스트 문자열
예약됨 ! * ' ( ) ; : @ & = + $ , / ? % # [ ] 제어 문자 또는 텍스트 문자열

유효한 URL을 작성할 때는 유효한 URL 문자 요약 표에 표시된 문자만 사용해야 합니다. 이러한 문자 집합을 사용하여 URL을 작성하다 보면 일반적으로 다음과 같이 누락과 대체라는 두 가지 문제가 발생합니다.

  • 처리하려는 문자가 위의 집합에 없는 경우. 예를 들어 上海+中國 등의 외국어 문자는 위의 문자를 사용하여 인코딩해야 합니다. 관례적으로 URL 내에서 허용되지 않는 공백은 더하기 문자('+')를 사용해서 표현하기도 합니다.
  • 예약된 문자로 위 집합에 포함된 문자를 문자 그대로 사용해야 하는 경우. 예를 들어 ?는 URL 내에서 쿼리 문자열의 시작을 나타내는 데 사용되는데, '? and the Mysterions'라는 문자열을 사용하려면 '?' 문자를 인코딩해야 합니다.

URL 인코딩이 필요한 모든 문자는 '%' 문자 및 UTF-8 문자에 해당하는 2자리 16진수 값을 사용하여 인코딩됩니다. 예를 들어 UTF-8 형식의 上海+中國%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B로 URL 인코딩됩니다. ? and the Mysterians 문자열은 %3F+and+the+Mysterians 또는 %3F%20and%20the%20Mysterians로 URL 인코딩됩니다.

인코딩이 필요한 일반 문자

일부 일반 문자는 다음과 같이 인코딩되어야 합니다.

안전하지 않은 문자 인코딩된 값
우주 %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

때로는 사용자가 입력한 URL을 수신하여 변환하는 과정이 까다로울 수 있습니다. 예를 들어 사용자가 주소를 '5th&Main St.'로 입력할 수 있습니다. 일반적으로 URL은 해당 부분을 사용하여 구성해야 하므로 모든 사용자 입력은 리터럴 문자로 취급해야 합니다.

또한 URL은 모든 Google Maps Platform 웹 서비스 및 정적 웹 API에서 8,192자(영문 기준)로 제한됩니다. 대부분의 서비스에서는 이러한 글자 수 제한에 도달하는 일이 거의 없습니다. 그러나 URL을 길게 만드는 매개변수가 포함된 서비스도 없지는 않습니다.

적절한 Google API 사용

제대로 설계되지 않은 API 클라이언트는 인터넷과 Google 서버에 필요한 부하를 더 많이 초래할 수 있습니다. 이 섹션에는 API 클라이언트의 모범 사례가 포함되어 있습니다. 이러한 권장사항을 따르면 애플리케이션이 실수로 API를 악용하여 차단되는 것을 방지할 수 있습니다.

지수 백오프

드물지만 요청을 처리하는 중에 문제가 발생할 수 있습니다. 4XX 또는 5XX HTTP 응답 코드를 수신하거나 클라이언트와 Google 서버 간의 어딘가에 TCP 연결이 실패할 수 있습니다. 원래 요청이 실패한 경우 후속 요청이 성공할 수 있으므로 요청을 다시 시도하는 것이 좋습니다. 그러나 단순히 Google 서버에 반복적으로 요청하는 루프를 반복하지 않는 것이 중요합니다. 이 루프 동작은 클라이언트와 Google 간에 네트워크를 과부하시켜 많은 당사자에게 문제를 일으킬 수 있습니다.

따라서 시도 사이의 지연 시간을 늘려 재시도하는 것이 훨씬 좋습니다. 일반적으로 지연 시간은 각 시도의 곱셈 요인에 의해 증가합니다. 이 접근 방식을 지수 백오프라고 합니다.

예를 들어 Time Zone API에 이 요청을 실행하려는 애플리케이션을 생각해 보세요.

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=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}")

애플리케이션 호출 체인에 더 높은 코드가 재시도되어 빠르게 연속적으로 요청을 반복할 수 없도록 주의해야 합니다.

동기화된 요청

Google API에 대한 다수의 동기화된 요청은 Google 인프라의 DDoS (분산 서비스 거부) 공격처럼 보일 수 있으며 그에 따라 처리됩니다. 이를 방지하려면 API 요청이 클라이언트 간에 동기화되지 않도록 해야 합니다.

예를 들어, 현재 시간대의 시간을 표시하는 애플리케이션을 생각해 봅시다. 이 애플리케이션은 표시된 시간을 업데이트할 수 있도록 클라이언트 운영체제에서 분 시작 시점에 절전 모드를 해제하는 알람을 설정합니다. 애플리케이션은 이 알람과 연결된 처리의 일부로 API를 호출해서는 안 됩니다.

고정 알람에 대한 응답으로 API를 호출하는 것은 시간 경과에 따라 균일하게 분산되지 않고 여러 기기 간에도 API 호출이 분 시작 부분에 동기화되므로 좋지 않습니다. 잘못 설계된 애플리케이션은 분 단위로 시작할 때 60배 정상 속도로 트래픽이 급증합니다.

이 문제를 해결하려면 두 번째 알람을 임의로 선택한 시간으로 설정하도록 설계하면 됩니다. 두 번째 알람이 발생하면 애플리케이션은 필요한 모든 API를 호출하고 결과를 저장합니다. 애플리케이션이 분 시작 시점에 디스플레이를 업데이트하려는 경우에는 API를 다시 호출하기보다는 이전에 저장된 결과를 사용합니다. 이 접근 방식을 사용하면 API 호출이 시간 경과에 따라 고르게 분산됩니다. 또한 디스플레이가 업데이트될 때 API 호출이 렌더링을 지연시키지 않습니다.

분 시작 시점 외에 시간 경과에 따라 정확히 일치하지 않아야 하는 다른 동기화 시간은 주의하여 시작하게 되며, 매일 자정에 시작되도록 해야 합니다.

응답 처리

이 섹션에서는 웹 서비스 응답에서 이들 값을 동적으로 추출하는 방법에 대해 설명합니다.

Google 지도 웹 서비스는 이해하기 쉽지만 사용자 친화적이지 않은 응답을 제공합니다. 쿼리를 실행할 때 데이터 집합을 표시하는 대신 몇 가지 특정 값을 추출하는 것이 좋습니다. 일반적으로 웹 서비스의 응답을 파싱하고 관심 있는 값만 추출하는 것이 좋습니다.

사용하는 파싱 스키마는 JSON으로 출력을 반환하는지 여부에 따라 달라집니다. 이미 JSON 객체 형식의 JSON 응답은 클라이언트에서 자바스크립트 자체 내에서 처리될 수 있습니다.