스트리트 뷰 Static API 사용 권장사항

HTTP 인터페이스 모음인 Google Maps Platform 정적 웹 API는 웹페이지에 직접 삽입할 이미지를 생성합니다.

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

이 가이드에서는 이미지 및 웹 서비스 요청을 설정하고 서비스 응답을 처리하는 데 유용한 몇 가지 일반적인 관행을 설명합니다. 스트리트 뷰 Static API에 대한 자세한 내용은 개발자 가이드를 참고하세요.

스트리트 뷰 Static API는 정적 웹 API처럼 작동하는 반면 메타데이터 서비스는 웹 서비스 역할을 합니다. 메타데이터 서비스에 대한 자세한 내용은 스트리트 뷰 이미지 메타데이터를 참고하세요.

정적 웹 API란 무엇인가요?

Google Maps Platform 정적 웹 API를 사용하면 JavaScript나 동적 페이지 로드 없이도 웹페이지에 Google 지도 이미지를 삽입할 수 있습니다. 정적 웹 API는 표준 HTTPS 요청을 사용하여 전송되는 URL 매개변수를 기반으로 이미지를 만듭니다.

일반적인 스트리트 뷰 Static API 요청의 형식은 다음과 같습니다.

  https://www.googleapis.com/streetview/z/x/y?parameters

웹 서비스란 무엇인가요?

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

Maps API 웹 서비스는 특정 URL에 대한 HTTP 또는 HTTPS 요청을 사용하여 URL 매개변수 또는 JSON 형식 POST 데이터를 서비스에 인수로 전달합니다. 일반적으로 이러한 서비스는 애플리케이션에서 파싱하거나 처리할 수 있도록 응답 본문에 데이터를 JSON으로 반환합니다.

Street View Static API 메타데이터 요청은 다음과 같은 형식입니다.

https://maps.googleapis.com/maps/api/streetview/parameters

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

유효한 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에서 16, 384자(영문 기준)로 제한됩니다. 대부분의 서비스에서는 이러한 글자 수 제한에 도달하는 일이 거의 없습니다. 그러나 URL을 길게 만드는 매개변수가 포함된 서비스도 있습니다.

Google API의 정중한 사용

잘못 설계된 API 클라이언트는 인터넷과 서버에 과도한 부하를 줄 수 있습니다. 이 섹션에는 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 in the following code 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 the request didn't produce an IOError, parse the result.
            result = json.load(response)

            if result["status"] == "OK":
                return result["timeZoneId"]
            elif result["status"] != "UNKNOWN_ERROR":
                # Many API errors can't be fixed by a retry, such as
                # INVALID_REQUEST or ZERO_RESULTS. Don't retry 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 on each 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 응답은 이미 JavaScript 객체 형식이므로 클라이언트의 JavaScript 자체 내에서 처리할 수 있습니다.