使用适用于 JavaScript 和 TypeScript 的 Azure 客户端库

若要以编程方式访问 Azure 服务,请使用适用于 JavaScript 的 Azure 客户端库。 通常,使用 azure-sdk 发布的 @azure npm 包范围来确定这些库的范围。

客户端库和 REST API 之间的差异

使用以下信息来了解何时使用哪种类型的访问。

  • Azure 客户端库是访问 Azure 服务的首选方法。 这些库将管理基于云的 Azure 平台 REST 请求(例如身份验证、重试和日志记录)所需的样板代码抽象化。
  • 在以下情况下,Azure REST API 是首选方法:
    • 使用不提供 Azure 客户端库的预览版服务。 将代码视为预览版,当服务随客户端库正式发布时,应更新该代码。
    • 需要直接进行 REST 调用,因为不希望整个 SDK 使用一个 REST API 或者希望对 HTTP 请求进行更深入的控制。

Azure 客户端和管理库

Azure 客户端库版本作为以下项提供:

  • 管理:使用管理库可以创建和管理 Azure 资源。 可以通过包名称中的 arm- 来识别这些库。 术语 ARM 指示 Azure 资源管理器。
  • 客户端:如果已存在 Azure 资源,请使用客户端库来使用它并与之交互。
    • 每个包 README.md 都包含文档和示例。

安装 Azure npm 包

可从 NPM 免费获取 Azure 客户端库。 根据需要安装各个 SDK。 每个 SDK 都提供 TypeScript 定义。

用于客户端/浏览器时,需要将 Azure 客户端库添加到捆绑进程。

使用 Azure npm 包示例代码

每个包都包括用于快速开始使用包的文档。 请参阅你使用的特定 NPM 包,了解如何使用它们。

提供身份验证凭据

Azure 客户端库需要凭据来向 Azure 平台进行身份验证@azure/identity 提供的凭据类具有以下几个好处:

  • 快速载入
  • 最安全的方法
  • 将身份验证机制与代码分开。 这样即使在凭据不同时,也可以在本地和 Azure 平台上使用相同的代码。
  • 提供链式身份验证,以便可以使用多种机制。

创建 SDK 客户端并调用方法

以编程方式创建凭据后,将凭据传递给 Azure 客户端。 客户端可能需要其他信息,例如订阅 ID 或服务终结点。 Azure 门户中提供这些值,它们可用于你的资源。

下面的代码示例使用 DefaultAzureCredential 和 arm 订阅客户端库列出此凭据有权读取的订阅。

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

结果的异步分页

SDK 方法可以返回异步迭代器 PagedAsyncIterableIterator,以允许获得异步结果。 结果可能会使用分页和延续令牌来分解结果集。

以下 JavaScript 示例演示了异步分页。 代码将人工短分页大小设置为 2,以便快速直观地演示在调试中运行示例代码时的过程。

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

详细了解 Azure 上的分页和迭代器:

长期运行的操作

SDK 方法可以返回长期操作 (LRO) 原始响应。 此响应包括以下信息:

  • 请求已完成
  • 请求仍在处理中

以下 JavaScript 示例使用 .pollUntildone() 演示如何等待 LRO 完成,然后继续。

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

详细了解 Azure 上的长期操作:

取消异步操作

@azure/abort-controller 包提供 AbortController 和 AbortSignal 类。 使用 AbortController 创建 AbortSignal,然后可以将其传递给 Azure SDK 操作以取消挂起的工作。 Azure SDK 操作可以:

  • 基于自己的逻辑中止
  • 基于超时限制中止
  • 基于父任务的信号中止
  • 基于父任务的信号或超时限制中止

了解详细信息:

SDK 中的详细日志记录

使用 Azure SDK 时,有时可能需要调试应用程序。

  • 若要在生成时启用日志记录,请将 AZURE_LOG_LEVEL 环境变量设置为 info

  • 要在运行时启用日志记录,请使用 @azure/logger 包:

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

捆绑

了解如何使用 Azure SDK 进行捆绑:

后续步骤