JavaScript/TypeScript REST SDK 개발자 가이드(미리 보기)

Azure Maps JavaScript/TypeScript REST SDK(JavaScript SDK)는 Azure Maps Search 서비스를 사용한 검색(예: 주소 검색, 도시 또는 국가 경계 검색, 좌표 검색)을 지원합니다. 이 문서는 Azure Maps의 기능을 통합하는 위치 인식 애플리케이션 빌드를 시작하는 데 도움이 됩니다.

참고 항목

Azure Maps JavaScript SDK는 Node.js의 LTS 버전을 지원합니다. 자세한 내용은 Node.js 릴리스 작업 그룹을 참조하세요.

필수 조건

프로그래밍 방식으로 Azure Maps 계정을 만들 수 있습니다. 다음은 Azure CLI를 사용하는 예입니다.

az maps account create --kind "Gen2" --account-name "myMapAccountName" --resource-group "<resource group>" --sku "G2"

Node.js 프로젝트 만들기

다음 예에서는 npm을 사용하여 mapsDemo라는 이름의 Node.js 프로그램과 새 디렉터리를 만듭니다.

mkdir mapsDemo
cd mapsDemo
npm init

검색 패키지 설치

Azure Maps JavaScript SDK를 사용하려면 검색 패키지를 설치해야 합니다. 검색, 라우팅, 렌더링 및 지리적 위치를 포함한 각 Azure Maps 서비스는 각각 자체 패키지에 있습니다.

npm install @azure-rest/maps-search

패키지가 설치되면 mapsDemo 디렉터리에 search.js 파일을 만듭니다.

mapsDemo
+-- package.json
+-- package-lock.json
+-- node_modules/
+-- search.js

Azure Maps 서비스

서비스 이름 NPM 패키지 샘플
Search @azure-rest/maps-search 검색 샘플
Route @azure-rest/maps-route 경로 샘플
렌더링 @azure-rest/maps-render 렌더링 샘플
지리적 위치 @azure-rest/maps-geolocation 지리적 위치 샘플

MapsSearchClient 만들기 및 인증

Azure Maps 검색 API에 액세스하는 데 사용되는 MapsSearchClient 개체를 만들 때 인증을 위해 credential 개체가 필요합니다. Microsoft Entra 자격 증명 또는 Azure 구독 키를 사용하여 인증할 수 있습니다. 자세한 내용은 Azure Maps로 인증을 참조하세요.

MapsSearchClient는 Azure Maps 검색 라이브러리를 사용하는 개발자를 위한 기본 인터페이스입니다. 사용 가능한 검색 방법에 대한 자세한 내용은 Azure Maps Search 클라이언트 라이브러리를 참조하세요.

Microsoft Entra 자격 증명 사용

Azure ID 라이브러리를 사용하여 Microsoft Entra ID로 인증을 받을 수 있습니다. DefaultAzureCredential 공급자를 사용하려면 @azure/identity 패키지를 설치해야 합니다.

npm install @azure/identity

새 Microsoft Entra 애플리케이션을 등록하고 필요한 역할을 서비스 주체에 할당하여 Azure Maps에 대한 액세스 권한을 부여해야 합니다. 자세한 내용은 비 Azure 리소스의 디먼 호스트를 참조하세요. 애플리케이션(클라이언트) ID, 디렉터리(테넌트) ID 및 클라이언트 암호가 반환됩니다. 이 값을 복사하여 안전한 장소에 저장합니다. 다음 단계에서 필요합니다.

애플리케이션(클라이언트) ID, 디렉터리(테넌트) ID, Microsoft Entra 애플리케이션의 클라이언트 암호 및 맵 리소스의 클라이언트 ID 값을 환경 변수로 설정합니다.

환경 변수 설명
AZURE_CLIENT_ID 등록된 애플리케이션의 애플리케이션(클라이언트) ID
AZURE_CLIENT_SECRET 등록된 애플리케이션의 클라이언트 암호 값
AZURE_TENANT_ID 등록된 애플리케이션의 디렉터리(테넌트) ID
MAPS_CLIENT_ID Azure Maps 계정의 클라이언트 ID

이러한 변수에 대해 .env 파일을 사용할 수 있습니다. dotenv 패키지를 설치해야 합니다.

npm install dotenv

그런 다음 mapsDemo 디렉터리에 .env 파일을 추가하고 다음 속성을 지정합니다.

AZURE_CLIENT_ID="<client-id>"
AZURE_CLIENT_SECRET="<client-secret>"
AZURE_TENANT_ID="<tenant-id>"
MAPS_CLIENT_ID="<maps-client-id>"

환경 변수가 만들어지면 JavaScript 코드에서 액세스할 수 있습니다.

const MapsSearch = require("@azure-rest/maps-search").default; 
const { DefaultAzureCredential } = require("@azure/identity"); 
require("dotenv").config(); 
 
const credential = new DefaultAzureCredential(); 
const client = MapsSearch(credential, process.env.MAPS_CLIENT_ID); 

구독 키 자격 증명 사용

Azure Maps 구독 키로 인증할 수 있습니다. 구독 키는 다음 스크린샷과 같이 Azure Maps 계정의 인증 섹션에서 찾을 수 있습니다.

Screenshot showing your Azure Maps subscription key in the Azure portal.

Azure Core Authentication Package에서 제공하는 AzureKeyCredential 클래스에 구독 키를 전달해야 합니다. 보안상의 이유로 키를 소스 코드에 포함하는 것보다 환경 변수로 지정하는 것이 좋습니다.

이 작업을 수행하려면 .env 파일을 사용하여 구독 키 변수를 저장합니다. 값을 검색하려면 dotenv 패키지를 설치해야 합니다.

npm install dotenv

다음으로 mapsDemo 디렉터리에 .env 파일을 추가하고 속성을 지정합니다.

MAPS_SUBSCRIPTION_KEY="<subscription-key>"

환경 변수가 만들어지면 JavaScript 코드에서 액세스할 수 있습니다.

const MapsSearch = require("@azure-rest/maps-search").default;
const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

const credential = new AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY);
const client = MapsSearch(credential);

SAS(공유 액세스 서명) 토큰 자격 증명 사용

SAS(공유 액세스 서명) 토큰은 JWT(JSON 웹 토큰) 형식을 사용하여 만든 인증 토큰이며 Azure Maps REST API에 애플리케이션에 대한 인증을 증명하기 위해 암호화 서명됩니다.

AzureMapsManagementClient.accounts.listSas 패키지를 사용하여 SAS 토큰을 가져올 수 있습니다. AzureMapsManagementClient 만들기 및 인증 섹션에 따라 먼저 설정합니다.

둘째, Azure Maps에 대한 관리 ID를 따라 Azure Maps 계정에 대한 관리 ID를 만듭니다. 관리 ID의 보안 주체 ID(개체 ID)를 복사합니다.

다음으로, Azure Core 인증 패키지 패키지를 설치하여 AzureSASCredential을 사용합니다.

npm install @azure/core-auth

마지막으로 SAS 토큰을 사용하여 클라이언트를 인증할 수 있습니다.

  const MapsSearch = require("@azure-rest/maps-search").default;
  const { AzureSASCredential } = require("@azure/core-auth");
  const { DefaultAzureCredential } = require("@azure/identity");
  const { AzureMapsManagementClient } = require("@azure/arm-maps");

  const subscriptionId = "<subscription ID of the map account>"
  const resourceGroupName = "<resource group name of the map account>";
  const accountName = "<name of the map account>";
  const mapsAccountSasParameters = {
    start: "<start time in ISO format>", // e.g. "2023-11-24T03:51:53.161Z"
    expiry: "<expiry time in ISO format>", // maximum value to start + 1 day
    maxRatePerSecond: 500,
    principalId: "<principle ID (object ID) of the managed identity>",
    signingKey: "primaryKey",
  };
  const credential = new DefaultAzureCredential();
  const managementClient = new AzureMapsManagementClient(credential, subscriptionId);
  const {accountSasToken} = await managementClient.accounts.listSas(
    resourceGroupName,
    accountName,
    mapsAccountSasParameters
  );
  if (accountSasToken === undefined) {
    throw new Error("No accountSasToken was found for the Maps Account.");
  }
  const sasCredential = new AzureSASCredential(accountSasToken);
  const client = MapsSearch(sasCredential);

지오코딩

다음 코드 조각은 간단한 콘솔 애플리케이션에서 @azure-rest/maps-search 패키지를 가져오고, GetGeocoding 쿼리를 사용하여 주소의 좌표를 가져오는 방법을 보여 줍니다.

const MapsSearch = require("@azure-rest/maps-search").default;
const { isUnexpected } = require("@azure-rest/maps-search");
const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

async function main() {
  const credential = new AzureKeyCredential(
    process.env. MAPS_SUBSCRIPTION_KEY
  );
  const client = MapsSearch(credential);

  const response = await client.path("/geocode", "json").get({
    queryParameters: {
      query: "1301 Alaskan Way, Seattle, WA 98101, US",
    },
  });
  if (isUnexpected(response)) {
    throw response.body.error;
  }
  const [ lon, lat ] = response.body.features[0].geometry.coordinates;
  console.log(`The coordinate is: (${lat}, ${lon})`);
}

main().catch((err) => {
  console.error(err);
});

이 코드 조각은 Azure Maps Search 클라이언트 라이브러리의 MapsSearch 메서드를 사용하여 Azure 자격 증명으로 client 개체를 만드는 방법을 보여 주는 코드 조각입니다. Azure Maps 구독 키 또는 Microsoft Entra 자격 증명을 사용할 수 있습니다. path 매개 변수는 API 엔드포인트(이 경우 "/geocode")를 지정합니다. get 메서드는 쿼리 매개 변수를 사용하여 HTTP GET 요청을 보냅니다. 쿼리는 "1301 Alaskan Way, Seattle, WA 98101, US"의 좌표를 검색합니다. SDK는 결과를 GeocodingResponseOutput 개체로 반환하고 콘솔에 씁니다. 이 예에서 결과는 신뢰도 점수에 따라 정렬되며 첫 번째 결과만 화면에 표시됩니다. 자세한 내용은 GetGeocoding을 참조하세요.

Node.js로 search.js 실행:

node search.js 

일괄 처리 역방향 지오코딩

Azure Maps Search는 일부 일괄 처리 쿼리 방법도 제공합니다. 다음 예제에서는 일괄 처리 역방향 검색 방법을 호출하는 방법을 보여 줍니다.

  const batchItems = [
    // This is an invalid query
    { coordinates: [2.294911, 148.858561] },
    {
      coordinates: [-122.34255, 47.6101],
    },
    { coordinates: [-122.33817, 47.6155] },
  ];
  const response = await client.path("/reverseGeocode:batch").post({
    body: { batchItems },
  });

이 예제에서는 요청 본문의 batchItems에 세 개의 좌표가 포함됩니다. 첫 번째 항목은 유효하지 않습니다. 유효하지 않은 항목을 처리하는 방법을 보여 주는 예는 실패한 요청 처리를 참조하세요.

응답을 받으면 다음과 같이 로그할 수 있습니다.

 
function logResponseBody(resBody) {
  const { summary, batchItems } = resBody;

  const { totalRequests, successfulRequests } = summary;
  console.log(`${successfulRequests} out of ${totalRequests} requests are successful.`);

  batchItems.forEach(({ response }, idx) => {
    if (response.error) {
      console.log(`Error in ${idx + 1} request: ${response.error.message}`);
    } else {
      console.log(`Results in ${idx + 1} request:`);
      response.features.forEach((feature) => {
        console.log(`  ${feature.properties.address.freeformAddress}`);
      });
    }
  });
} 

실패한 요청 처리

응답 일괄 처리 항목에서 error 속성을 확인하여 실패한 요청을 처리합니다. 다음의 완료된 일괄 처리 역방향 검색 예에서 logResponseBody 함수를 참조하세요.

완료된 일괄 처리 역방향 검색 예

역방향 주소 일괄 처리 검색 예의 전체 코드:

const MapsSearch = require("@azure-rest/maps-search").default,
  { isUnexpected } = require("@azure-rest/maps-search");
const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

async function main() {
  const credential = new AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY);
  const client = MapsSearch(credential);

  const batchItems = [
    // This is an invalid query
    { coordinates: [2.294911, 148.858561] },
    {
      coordinates: [-122.34255, 47.6101],
    },
    { coordinates: [-122.33817, 47.6155] },
  ];

  const response = await client.path("/reverseGeocode:batch").post({
    body: { batchItems },
  });

  if (isUnexpected(response)) {
    throw response.body.error;
  }

  logResponseBody(resumeResponse.body);
}

function logResponseBody(resBody) {
  const { summary, batchItems } = resBody;

  const { totalRequests, successfulRequests } = summary;
  console.log(`${successfulRequests} out of ${totalRequests} requests are successful.`);

  batchItems.forEach(({ response }, idx) => {
    if (response.error) {
      console.log(`Error in ${idx + 1} request: ${response.error.message}`);
    } else {
      console.log(`Results in ${idx + 1} request:`);
      response.features.forEach((feature) => {
        console.log(`  ${feature.properties.address.freeformAddress}`);
      });
    }
  });
} 

main().catch(console.error);

V1 SDK 사용

V2에서 모든 V1 기능을 사용할 수 있도록 하기 위해 작업 중이므로 그때까지 필요한 경우 다음 V1 SDK 패키지를 설치합니다.

npm install @azure-rest/map-search-v1@npm:@azure-rest/map-search@^1.0.0
npm install @azure-rest/map-search-v2@npm:@azure-rest/map-search@^2.0.0

그런 후, 다음 두 패키지를 가져올 수 있습니다.

const MapsSearchV1 = require("@azure-rest/map-search-v1").default;
const MapsSearchV2 = require("@azure-rest/map-search-v2").default;

다음 예제에서는 주소를 수락하고 주변의 POI를 검색하는 함수를 만드는 방법을 보여 줍니다. V2 SDK를 사용하여 주소의 좌표를 가져오고(/geocode), V1 SDK를 사용하여 주위의 POI를 검색합니다(/search/nearby).

const MapsSearchV1 = require("@azure-rest/map-search-v1").default;
const MapsSearchV2 = require("@azure-rest/map-search-v2").default;
const { AzureKeyCredential } = require("@azure/core-auth");
const { isUnexpected: isUnexpectedV1 } = require("@azure-rest/maps-search-v1");
const { isUnexpected: isUnexpectedV2 } = require("@azure-rest/maps-search-v2");
require("dotenv").config();

/** Initialize the MapsSearchClient */
const clientV1 = MapsSearchV1(new AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY));
const clientV2 = MapsSearchV2(new AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY));

async function searchNearby(address) {
  /** Make a request to the geocoding API */
  const geocodeResponse = await clientV2
    .path("/geocode")
    .get({ queryParameters: { query: address } });
  /** Handle error response */
  if (isUnexpectedV2(geocodeResponse)) {
    throw geocodeResponse.body.error;
  }

  const [lon, lat] = geocodeResponse.body.features[0].geometry.coordinates;
  
  /** Make a request to the search nearby API */
  const nearByResponse = await clientV1.path("/search/nearby/{format}", "json").get({
    queryParameters: { lat, lon },
  });
  /** Handle error response */
  if (isUnexpectedV1(nearByResponse)) {
    throw nearByResponse.body.error;
  }
  /** Log response body */
  for(const results of nearByResponse.body.results) {
    console.log(
      `${result.poi ? result.poi.name + ":" : ""} ${result.address.freeformAddress}. (${
        result.position.lat
      }, ${result.position.lon})\n`
    );
  }
}

async function main(){
  searchNearBy("15127 NE 24th Street, Redmond, WA 98052");
}

main().catch((err) => {
    console.log(err);
})

추가 정보