Directions API 웹 서비스를 사용한 권장사항

Google Maps Platform 웹 서비스는 Google Cloud의 HTTP 인터페이스 모음입니다. 서비스를 제공합니다.

이 가이드에서는 웹 서비스 서비스 응답을 처리하는 데 사용할 수 있는 도구 집합입니다 개발자 가이드를 참고하세요. Directions API의 전체 문서를 참고하세요.

웹 서비스란 무엇인가요?

Google Maps Platform 웹 서비스는 외부 서비스 및 지도 애플리케이션 내의 데이터를 사용할 수 있습니다. 이러한 서비스는 에 따라 지도와 함께 사용하도록 라이선스 제한 을 참조하세요.

Maps API 웹 서비스는 특정 URL에 대한 HTTP(S) 요청을 사용하여 URL 매개변수 및/또는 서비스에 대한 인수로 JSON 형식의 POST 데이터를 제공합니다. 일반적으로 이러한 서비스는 파싱을 위한 JSON 또는 XML 형식의 응답 본문 처리되어야 합니다.

일반적인 Directions API 요청은 일반적으로 다음 양식을 제출해 주세요.

https://maps.googleapis.com/maps/api/directions/output?parameters

여기서 output는 응답 형식 (일반적으로 json 또는 xml).

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

적절한 Google API 사용

잘못 설계된 API 클라이언트는 인터넷과 서버 모두에서 필요한 것보다 더 많은 부하를 Google 서버. 이 섹션에는 API 클라이언트의 모범 사례가 포함되어 있습니다. 팔로우 중 본 모범 사례는 애플리케이션이 살펴보겠습니다

지수 백오프

드물지만 요청을 처리하는 과정에서 문제가 발생할 수 있습니다. 4XX 또는 5XX HTTP 요청이 또는 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 호출은 디스플레이가 있습니다.

분 시작을 제외하고 다른 일반적인 동기화 시간은 주의해야 합니다. 아닙니다.

응답 처리

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

Google 지도 웹 서비스는 이해할 수 있지만 사용자 친화적이지 않습니다. 쿼리를 수행할 때는 더 구체적인 데이터 세트를 표시하려면 값으로 사용됩니다. 일반적으로 웹에서 응답을 파싱합니다 확인하고 관심 있는 값만 추출하세요.

사용하는 파싱 스키마는 반환되는지 여부에 따라 다릅니다. 출력됩니다. JSON 응답은 이미 JavaScript 객체이며 JavaScript 자체 내에서 처리될 수 있습니다. 실행할 수 있습니다 XML 응답은 XML 프로세서를 사용하여 처리해야 합니다. XML 형식 내에서 요소를 처리하기 위한 XML 쿼리 언어를 지원합니다. YouTube는 XPath를 이는 일반적으로 XML 처리에서 지원되므로 제공합니다

XPath로 XML 처리

XML은 텍스트, 이미지, 오디오, 동영상 등 데이터를 교환할 수 있습니다. JSON, XML만큼 가볍지는 않지만 더 많은 언어 지원과 더 강력한 도구를 제공합니다. 코드 대상 예를 들어, Java에서 XML을 처리하는 것은 javax.xml 패키지.

XML 응답을 처리할 때는 적절한 XML 문서에서 노드를 선택하기 위한 쿼리 언어를 사용하는 대신 요소가 내부의 절대 위치에 있다고 가정하는 것보다 XML 마크업. XPath 노드와 요소를 고유하게 설명하기 위한 언어 구문입니다. . XPath 표현식을 사용하면 XML 응답 문서 내의 특정 콘텐츠를 식별합니다.

XPath 식

XPath에 익숙해지면 AI를 개발할 수 있는 가능성이 강력한 파싱 스키마가 필요합니다. 이 섹션에서는 요소가 XPath로 처리되므로 복잡한 쿼리를 작성할 수 있습니다.

XPath는 표현식을 사용하여 XML 내에서 요소를 선택합니다. 문서로 대체되었으며 디렉터리 경로에 사용되는 것과 유사한 구문을 사용합니다. 이 표현식은 XML 문서 내의 요소를 식별합니다. 트리 구조로 되어 있습니다. 일반적으로 XPath 표현식은 탐욕스럽기 때문에 입력한 기준과 일치하는 모든 노드를 검색합니다.

다음 추상 XML을 사용하여 예:

<WebServiceResponse>
 <status>OK</status>
 <result>
  <type>sample</type>
  <name>Sample XML</name>
  <location>
   <lat>37.4217550</lat>
   <lng>-122.0846330</lng>
  </location>
 </result>
 <result>
  <message>The secret message</message>
 </result>
</WebServiceResponse>

식에서 노드 선택

XPath 선택 항목이 노드를 선택합니다. 루트 노드 전체 문서가 포함됩니다. 다음을 사용하여 이 노드를 선택합니다. 특수 표현식 '/'. 참고로 루트는 노드는 XML 문서의 최상위 노드가 아닙니다. 사실 최상위 요소보다 한 수준 위에 있으며 있습니다.

요소 노드는 XML 내의 다양한 요소를 나타냅니다. 문서 트리를 생성합니다. <WebServiceResponse> 요소 예를 들어, 샘플 서비스의 내용을 참조하세요. kubectl 명령어 또는 존재 또는 부호로 표시되는 절대 또는 상대 경로 선행 '/' 부재 있습니다.

  • 절대 경로: '/WebServiceResponse/result' 표현식은 선택한 모든 <result> 노드를 <WebServiceResponse>의 하위 요소 노드입니다 이 두 요소는 모두 '/' 노드)
  • 현재 컨텍스트의 상대 경로: 표현식 'result' 모든 <result>과 일치 요소가 포함됩니다. 일반적으로 맥락에 대해 걱정할 필요가 없습니다. 단일 표현식을 통해 서비스 결과를 제공할 수 있습니다

이 표현식 중 하나는 덧셈을 통해 증가될 수 있습니다. 이중 슬래시('//')로 표시된 와일드 카드 경로의 문자 이 와일드카드는 영향을 줍니다. XPath 표현식 '//formatted_address' 예를 들어 은 현재 문서에서 해당 이름의 모든 노드와 일치합니다. //viewport//lat 표현식은 <viewport>를 추적할 수 있는 <lat> 요소 설정할 수 있습니다.

기본적으로 XPath 식은 모든 요소를 비교합니다. 술어, 대괄호 ([])로 묶입니다. XPath 표현식 '/GeocodeResponse/result[2]'는 항상 두 번째 결과를 예로 들 수 있습니다.

식의 유형
루트 노드
XPath 표현식: '/'
선택: <ph type="x-smartling-placeholder">
    <WebServiceResponse>
     <status>OK</status>
     <result>
      <type>sample</type>
      <name>Sample XML</name>
      <location>
       <lat>37.4217550</lat>
       <lng>-122.0846330</lng>
      </location>
     </result>
     <result>
      <message>The secret message</message>
     </result>
    </WebServiceResponse>
    
</ph>
절대 경로
XPath 표현식: '/WebServiceResponse/result'
선택: <ph type="x-smartling-placeholder">
    <result>
     <type>sample</type>
     <name>Sample XML</name>
     <location>
      <lat>37.4217550</lat>
      <lng>-122.0846330</lng>
     </location>
    </result>
    <result>
     <message>The secret message</message>
    </result>
    
</ph>
와일드카드가 있는 경로
XPath 표현식: '/WebServiceResponse//location'
선택: <ph type="x-smartling-placeholder">
    <location>
     <lat>37.4217550</lat>
     <lng>-122.0846330</lng>
    </location>
    
</ph>
조건자가 있는 경로
XPath 표현식: '/WebServiceResponse/result[2]/message'
선택: <ph type="x-smartling-placeholder">
    <message>The secret message</message>
    
</ph>
첫 번째 result의 모든 직계 하위 요소
XPath 표현식: '/WebServiceResponse/result[1]/*'
선택: <ph type="x-smartling-placeholder">
     <type>sample</type>
     <name>Sample XML</name>
     <location>
      <lat>37.4217550</lat>
      <lng>-122.0846330</lng>
     </location>
    
</ph>
nametype 텍스트가 'sample'인 result
XPath 표현식: '/WebServiceResponse/result[type/text()='sample']/name'
선택: <ph type="x-smartling-placeholder">
    Sample XML
    
</ph>

요소를 선택할 때 노드를 선택하고 해당 객체 내의 텍스트뿐만 아니라 일반적으로 일치하는 모든 노드를 반복하여 텍스트를 추출하려고 합니다. 나 텍스트 노드를 직접 일치시킬 수도 있습니다. 텍스트 노드 를 참조하세요.

XPath는 속성 노드도 지원합니다. 하지만 모든 Google Maps 웹 서비스는 속성이 없는 요소를 제공하므로 속성 일치가 필요하지 않습니다

식에서 텍스트 선택

XML 문서의 텍스트가 XPath 표현식으로 지정됩니다. 텍스트 노드 연산자를 통해 로드할 수 있습니다 연산자 'text()' 표시된 노드에서 텍스트를 추출함을 나타냅니다. 예를 들어 XPath 표현식 '//formatted_address/text()' 할 것이다 <formatted_address> 내의 모든 텍스트 반환 요소

식의 유형
모든 텍스트 노드(공백 포함)
XPath 표현식: '//text()'
선택: <ph type="x-smartling-placeholder">
    sample
    Sample XML

    37.4217550
    -122.0846330
    The secret message
    
</ph>
텍스트 선택
XPath 표현식: '/WebServiceRequest/result[2]/message/text()'
선택: <ph type="x-smartling-placeholder">
    The secret message
    
</ph>
컨텍스트에 따른 선택
XPath 표현식: '/WebServiceRequest/result[type/text() = 'sample']/name/text()'
선택: <ph type="x-smartling-placeholder">
    Sample XML
    
</ph>

또는 표현식을 평가하고 집합을 반환할 수 있습니다. 해당 '노드 집합'을 반복합니다. 추출하는 읽을 수 있습니다 아래 예시에서는 이 방법을 사용합니다.

XPath에 대한 자세한 내용은 XPath W3C 사양을 참조하세요.

Java에서 XPath 평가

Java는 XML 파싱 및 XPath 표현식 사용을 광범위하게 지원합니다. javax.xml.xpath.* 패키지 내 따라서 이 섹션의 샘플 코드는 Java를 사용하여 도 XML을 처리하고 XML 서비스 응답에서 데이터를 파싱하는 방법을 보여줍니다.

Java 코드에서 XPath를 사용하려면 먼저 XPathFactory의 인스턴스를 생성하고 이 팩토리에서 newXPath()를 호출하여 XPath 객체를 만듭니다. 그러면 이 객체는 전달된 XML을 evaluate() 메서드를 사용하여 XPath 표현식을 처리할 수 있습니다.

XPath 표현식을 평가할 때는 모든 '노드 세트'에 대해 반환될 수 있습니다. 이러한 결과가 Java 코드에서 DOM 노드로 반환되기 때문에 NodeList 객체 내 이러한 여러 값 해당 객체를 반복하여 텍스트 또는 값에서 노드라는 두 가지 리소스가 있습니다

다음 코드는 XPath를 만드는 방법을 보여줍니다. 객체에 XML 및 XPath 표현식을 할당하고 표현식을 사용하여 관련 콘텐츠를 출력합니다.

import org.xml.sax.InputSource;
import org.w3c.dom.*;
import javax.xml.xpath.*;
import java.io.*;

public class SimpleParser {

  public static void main(String[] args) throws IOException {

	XPathFactory factory = XPathFactory.newInstance();

    XPath xpath = factory.newXPath();

    try {
      System.out.print("Web Service Parser 1.0\n");

      // In practice, you'd retrieve your XML via an HTTP request.
      // Here we simply access an existing file.
      File xmlFile = new File("XML_FILE");

      // The xpath evaluator requires the XML be in the format of an InputSource
	  InputSource inputXml = new InputSource(new FileInputStream(xmlFile));

      // Because the evaluator may return multiple entries, we specify that the expression
      // return a NODESET and place the result in a NodeList.
      NodeList nodes = (NodeList) xpath.evaluate("XPATH_EXPRESSION", inputXml, XPathConstants.NODESET);

      // We can then iterate over the NodeList and extract the content via getTextContent().
      // NOTE: this will only return text for element nodes at the returned context.
      for (int i = 0, n = nodes.getLength(); i < n; i++) {
        String nodeString = nodes.item(i).getTextContent();
        System.out.print(nodeString);
        System.out.print("\n");
      }
    } catch (XPathExpressionException ex) {
	  System.out.print("XPath Error");
    } catch (FileNotFoundException ex) {
      System.out.print("File Error");
    }
  }
}