Use Azure client libraries for JavaScript and TypeScript

To programmatically access your Azure services, use the Azure client libraries for JavaScript. Typically, these libraries are scoped with the @azure npm package scope published by azure-sdk.

Differences between client libraries and REST APIs

Use the following information to understand when to use which type of access.

  • The Azure client libraries are the preferred method of accessing your Azure service. These libraries abstract away the boilerplate code required to manage cloud-based Azure platform REST requests such as authentication, retries, and logging.
  • Azure REST APIs are the preferred method if you are:
    • Working with preview services that do not have Azure client libraries available. Consider your code as preview, which should be updated when the service is generally available with client libraries.
    • Want to make REST calls directly because you don't want the entire SDK to use a single REST API or you want deeper control over the HTTP requests.

Azure client and management libraries

The Azure client library releases are available as:

  • Management: Management libraries enable you to create and manage Azure resources. You can recognize these libraries by arm- in their package names. The term ARM indicates the Azure Resource Manager.
  • Client: Given an Azure resource already exists, use the client libraries to consume it and interact with it.
    • Each package README.md includes documentation and samples.

Install Azure npm packages

Azure client libraries are freely available from NPM. Install individual SDKs as needed. Each SDK provides TypeScript definitions.

For client/browser usage, Azure client libraries need to be added to your bundling process.

Use Azure npm package sample code

Each package includes documentation to quickly get you started with the package. Refer to the specific NPM packages you use to learn how to use them.

Provide authentication credentials

The Azure client libraries require credentials to authenticate to the Azure platform. Credential classes provided by @azure/identity provide several benefits:

  • Fast onboarding
  • Most secure method
  • Separate the authentication mechanism from the code. This allows you to use the same code locally and on the Azure platform while the credentials are different.
  • Provide chained authentication so several mechanisms can be available.

Create an SDK client and call methods

Once you programmatically create a credential, pass the credential to your Azure client. The client may require additional information such as a subscription ID or service endpoint. These values are available in the Azure portal, for your resource.

The following code example uses the DefaultAzureCredential and the arm subscription client library to list subscriptions which this credential has access to read.

const {
  ClientSecretCredential,
  DefaultAzureCredential,
} = require("@azure/identity");
const { SubscriptionClient } = require("@azure/arm-subscriptions");
require("dotenv").config();

let credentials = null;

const tenantId = process.env["AZURE_TENANT_ID"];
const clientId = process.env["AZURE_CLIENT_ID"];
const secret = process.env["AZURE_CLIENT_SECRET"];

if (process.env.NODE_ENV && process.env.NODE_ENV === "production") {
  // production
  credentials = new DefaultAzureCredential();
} else {
  // development
  if (tenantId && clientId && secret) {
    console.log("development");
    credentials = new ClientSecretCredential(tenantId, clientId, secret);
  } else {
    credentials = new DefaultAzureCredential();
  }
}

async function listSubscriptions() {
  try {
    // use credential to authenticate with Azure SDKs
    const client = new SubscriptionClient(credentials);

    // get details of each subscription
    for await (const item of client.subscriptions.list()) {
      const subscriptionDetails = await client.subscriptions.get(
        item.subscriptionId
      );
      /* 
        Each item looks like:
      
        {
          id: '/subscriptions/123456',
          subscriptionId: '123456',
          displayName: 'YOUR-SUBSCRIPTION-NAME',
          state: 'Enabled',
          subscriptionPolicies: {
            locationPlacementId: 'Internal_2014-09-01',
            quotaId: 'Internal_2014-09-01',
            spendingLimit: 'Off'
          },
          authorizationSource: 'RoleBased'
        },
    */
      console.log(subscriptionDetails);
    }
  } catch (err) {
    console.error(JSON.stringify(err));
  }
}

listSubscriptions()
  .then(() => {
    console.log("done");
  })
  .catch((ex) => {
    console.log(ex);
  });

Asynchronous paging of results

An SDK method can return an asynchronous iterator, PagedAsyncIterableIterator, to allow for asynchronous results. The results may use paging and continuation tokens to break up result sets.

The following JavaScript example demonstrates asynchronous paging. The code sets an artificially short paging size of 2 in order to quickly and visually demonstrate the process when you run the sample code in debug.

const { BlobServiceClient } = require("@azure/storage-blob");

const blobAccountConnectionString = "REPLACE-WITH-YOUR-STORAGE-CONNECTION-STRING";
const blobAccountContainerName = "REPLACE-WITH-YOUR-STORAGE-CONTAINER-NAME";

const pageSize = 2;

const list = async () => {

  console.log(`List`);

  let continuationToken = "";
  let currentPage = 1;
  let containerClient=null;
  let currentItem = 1;

  // Get Blob Container - need to have items in container before running this code
  const blobServiceClient = BlobServiceClient.fromConnectionString(blobAccountConnectionString);
  containerClient = blobServiceClient.getContainerClient(blobAccountContainerName);

  do {

    // Get Page of Blobs
    iterator = (continuationToken != "") 
      ? containerClient.listBlobsFlat().byPage({ maxPageSize: pageSize, continuationToken }) 
      : containerClient.listBlobsFlat().byPage({ maxPageSize: pageSize });
    
    page = (await iterator.next()).value;

    // Display list
    if (page.segment?.blobItems) {
      console.log(`\tPage [${currentPage}] `);
      for (const blob of page.segment.blobItems) {
        console.log(`\t\tItem [${currentItem++}] ${blob.name}`);
      }
    };

    // Move to next page
    continuationToken = page.continuationToken;
    if (continuationToken) {
      currentPage++;
    }

  } while (continuationToken != "")
}

list(() => {
  console.log("done");
}).catch((ex) =>
  console.log(ex)
);

Learn more about paging and iterators on Azure:

Long running operations

An SDK method can return a long running operation (LRO) raw response. This response includes information including:

  • Your request completed
  • Your request is still in process

The following JavaScript example demonstrates how to wait for an LRO to complete, with .pollUntildone(), before continuing.

const { BlobServiceClient } = require("@azure/storage-blob");

const blobAccountConnectionString = "REPLACE-WITH-YOUR-STORAGE-CONNECTION-STRING";
const blobAccountContainerName = `test-${Date.now().toString()}`;

const files = [
  {
    "url": "https://github.com/Azure/azure-sdk-for-js/blob/main/README.md",
    "fileName": "README.md"
  },
  {
    "url": "https://github.com/Azure/azure-sdk-for-js/blob/main/gulpfile.ts",
    "fileName": "gulpfile.ts"
  },
  {
    "url": "https://github.com/Azure/azure-sdk-for-js/blob/main/rush.json",
    "fileName": "rush.json"
  },  
  {
    "url": "https://github.com/Azure/azure-sdk-for-js/blob/main/package.json",
    "fileName": "package.json"
  },
  {
    "url": "https://github.com/Azure/azure-sdk-for-js/blob/main/tsdoc.json",
    "fileName": "tsdoc.json"
  },
];

const upload = async() => {

  // get container client
  const blobServiceClient = BlobServiceClient.fromConnectionString(blobAccountConnectionString);

  // get container's directory client
  const containerClient = blobServiceClient.getContainerClient(blobAccountContainerName);

  files.forEach(async(file) =>{
    await (

      await containerClient
        .getBlobClient(file.fileName)
        .beginCopyFromURL(file.url)
  
    ).pollUntilDone();
  })
}

upload(() => {
  console.log("done");
}).catch((ex) =>
  console.log(ex)
);

Learn more about long running operations on Azure:

Canceling async operations

The @azure/abort-controller package provides AbortController and AbortSignal classes. Use the AbortController to create an AbortSignal, which can then be passed to Azure SDK operations to cancel pending work. Azure SDK operations can be:

  • Aborted based on your own logic
  • Aborted based on a timeout limit
  • Aborted based on a parent task's signal
  • Aborted based on a parent task's signal or a timeout limit

Learn more:

Verbose logging from the SDK

When using an Azure SDK, there may be times when you need to debug your application.

  • To enable logging at build-time, set the AZURE_LOG_LEVEL environment variable to info.

  • To enable logging at run-time, use the @azure/logger package:

    import { setLogLevel } from "@azure/logger";
    
    setLogLevel("info");
    

Bundling

Learn about bundling with the Azure SDK:

Next steps