Guia para desenvolvedores do SDK REST JavaScript/TypeScript (versão prévia)

O SDK REST do JavaScript/TypeScript para Azure Mapas (SDK do JavaScript) oferece suporte à pesquisa usando o serviço Pesquisa do Azure Mapas, permitindo ações como buscar um endereço, as fronteiras de uma cidade ou país e pesquisar por coordenadas. Este artigo ajudará você a começar a compilar aplicativos com reconhecimento de localização que incorporam o poder do Azure Mapas.

Observação

O SDK do JavaScript para Azure Mapas dá suporte à versão LTS do Node.js. Para obter mais informações, confira Grupo de trabalho de lançamento do Node.js.

Pré-requisitos

Dica

Você pode criar uma conta Azure Mapas programaticamente. Aqui está um exemplo usando a CLI do Azure:

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

Criar um projeto Node.js

O exemplo a seguir cria um diretório e, em seguida, um programa Node.js chamado mapsDemo usando npm:

mkdir mapsDemo
cd mapsDemo
npm init

Instalar o pacote de pesquisa

Para usar o SDK do JavaScript para Azure Mapas, você precisará instalar o pacote de pesquisa. Cada um dos serviços do Azure Mapas, incluindo pesquisa, roteamento, renderização e geolocalização, estão cada um no próprio pacote.

npm install @azure-rest/maps-search

Depois que o pacote for instalado, crie um arquivo search.js no diretório mapsDemo:

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

Serviços do Azure Mapas

Nome do serviço Pacotes npm Exemplos
Pesquisa @azure-rest/maps-search exemplos de pesquisas
Route @azure-rest/maps-route exemplos de rota
Render @azure-rest/maps-render renderizar amostra
Geolocalização @azure-rest/maps-geolocation exemplo de geolocalização

Criar e autenticar um MapsSearchClient

Você precisará de um objeto credential para autenticação ao criar o objeto MapsSearchClient usado para acessar as APIs de pesquisa do Azure Mapas. Você pode usar uma credencial do Microsoft Entra ou uma chave de assinatura do Azure para autenticar. Para obter mais informações sobre autenticação, confira Autenticação no Azure Mapas.

Dica

O MapsSearchClient é a interface principal para desenvolvedores que usam a biblioteca de pesquisa do Azure Mapas. Consulte biblioteca de clientes de pesquisa do Azure Mapas para saber mais sobre os métodos de pesquisa disponíveis.

Como usar uma credencial do Microsoft Entra

Você pode autenticar com o Microsoft Entra ID usando a biblioteca de Identidade do Azure. Para usar o provedor DefaultAzureCredential, você precisará instalar o pacote @azure/identity:

npm install @azure/identity

Você precisará registrar o novo aplicativo do Microsoft Entra e permitir acesso ao Azure Mapas atribuindo a função necessária à entidade de serviço. Para obter mais informações, confira Hospedar um daemon em recursos que não são do Azure. A ID do aplicativo (cliente), uma ID de diretório (locatário) e um segredo do cliente são retornados. Copie esses valores e armazene-os em um local seguro. Você precisará deles nas etapas a seguir.

Defina os valores da ID do aplicativo (cliente), da ID do diretório (locatário) e do segredo do cliente do aplicativo do Microsoft Entra e a ID do cliente do recurso de mapa como variáveis de ambiente:

Variável de ambiente Descrição
AZURE_CLIENT_ID ID do aplicativo (cliente) no aplicativo registrado
AZURE_CLIENT_SECRET O valor do segredo do cliente no aplicativo registrado
AZURE_TENANT_ID ID do diretório (locatário) no aplicativo registrado
MAPS_CLIENT_ID A ID do cliente na conta do Azure Mapas

Você pode usar um arquivo .env para essas variáveis. Você precisará instalar o pacote dotenv:

npm install dotenv

Em seguida, adicione um arquivo .env no diretório mapsDemo e especifique estas propriedades:

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

Depois que as variáveis de ambiente forem criadas, você poderá acessá-las no código 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); 

Usando uma credencial de chave de assinatura

Você pode autenticar com sua chave de assinatura do Azure Mapas. Sua chave de assinatura pode ser encontrada na seção Autenticação na conta do Azure Mapas, conforme mostrado na seguinte captura de tela:

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

Você precisa passar a chave da assinatura para a classe AzureKeyCredential fornecida pelo Pacote de Autenticação do Azure Core. Por motivos de segurança, é melhor especificar a chave como uma variável de ambiente do que incluí-la no código-fonte.

Você pode fazer isso usando um arquivo .env para armazenar a variável de chave de assinatura. Você precisará instalar o pacote dotenv para recuperar o valor:

npm install dotenv

Em seguida, adicione um arquivo .env no diretório mapsDemo e especifique a propriedade:

MAPS_SUBSCRIPTION_KEY="<subscription-key>"

Depois que a variável de ambiente for criada, você poderá acessá-la em seu código 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);

Utilizando um Token de Credencial de Assinatura de Acesso Compartilhado (SAS)

Os tokens de SAS (assinatura de acesso compartilhado) são tokens de autenticação criados usando o formato JWT (token Web JSON) e são assinados criptograficamente para provar a autenticação de um aplicativo para a API REST do Azure Mapas.

Você pode obter o token SAS usando o pacote AzureMapsManagementClient.accounts.listSas. Siga a seção Criar e autenticar um AzureMapsManagementClient para a configuração inicial.

Em seguida, siga as etapas em Identidades gerenciadas para o Azure Mapas para criar uma identidade gerenciada para sua conta do Azure Mapas. Copie o ID da entidade de segurança (ID do objeto) da identidade gerenciada.

Em seguida, instale o Azure Core Authentication Package para usar AzureSASCredential:

npm install @azure/core-auth

Por fim, você pode usar o token SAS para autenticar o cliente:

  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);

Geocodificação

O seguinte trecho de código mostra como, em um aplicativo de console simples, importar o pacote @azure-rest/maps-search e obter as coordenadas de um endereço usando a consulta 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);
});

Este trecho de código mostra como usar o método MapsSearch da biblioteca do cliente de Pesquisa do Azure Mapas para criar um objeto client com suas credenciais do Azure. Você pode usar sua chave de assinatura do Azure Mapas ou a credencial do Microsoft Entra. O parâmetro path especifica o ponto de extremidade da API, que é "/geocode" nesse caso. O método get envia uma solicitação HTTP GET com os parâmetros da consulta. A consulta procura pela coordenada "1301 Alaskan Way, Seattle, WA 98101, US". O SDK retorna os resultados como um objeto GeocodingResponseOutput e os grava no console. Os resultados são ordenados pela pontuação de confiança e, nesse exemplo, apenas o primeiro resultado é mostrado na tela. Para mais informações, confira GetGeocoding.

Execute search.js com Node.js:

node search.js 

Geocódigo reverso em lote

A Pesquisa do Azure Mapas também fornece alguns métodos de consulta em lote. O seguinte exemplo demonstra como chamar os métodos de pesquisa reversa em lote:

  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 },
  });

Neste exemplo, três coordenadas são incluídas no batchItems do corpo da requisição. O primeiro item é inválido; confira Entrega de solicitações com falha para um exemplo mostrando como lidar com o item inválido.

Depois de obter a resposta, você poderá registrá-la:

 
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}`);
      });
    }
  });
} 

Tratamento de solicitações com falha

Manipule solicitações com falha verificando a propriedade error no item do lote de resposta. Confira a função logResponseBody no exemplo de pesquisa reversa em lotes concluída a seguir.

Exemplo de pesquisa reversa em lotes concluída

O código completo do exemplo de pesquisa de endereço reversa em lotes:

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);

Usar o SDK V1

Enquanto trabalhamos para disponibilizar todos os recursos da V1 na V2, instale os seguintes pacotes do SDK V1 se necessário:

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

Em seguida, você pode importar os dois pacotes:

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

O exemplo a seguir demonstra como criar uma função que aceita um endereço e busca POIs ao seu redor. Use o SDK V2 para obter as coordenadas do endereço (/geocode) e do SDK V1 para buscar POIs em torno dele (/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);
})

Informações adicionais