azure-sdk-for-js/documentation/MIGRATION-guide-for-next-ge...

17 KiB

Guide for migrating to the next generation of Azure JavaScript SDK for Management Libraries

This document shows the customers of the JavaScript/TypeScript management libraries on how to migrate their code to use the next-generation libraries.

For new customers of the JavaScript/TypeScript SDK (azure-sdk-for-js), please see quick start for next generation.

Current status

Currently, we have released GA version of selected services including @azure/arm-resources, @azure/arm-storage, @azure/arm-compute, @azure/arm-network. We are actively working on releasing more packages and eventually cover all Azure services. Please find the latest version of those libraries in npm and have a try.

Why Switching to the next-generation

Compared to the current management libraries, the next-generation libraries have the following changes:

  1. Authentication: The packages @azure/ms-rest-nodeauth or @azure/ms-rest-browserauth are no longer supported. Use package @azure/identity instead. Select a credential from Azure Identity examples based on the authentication method of your choice.
  2. Callbacks: Method overloads that use callbacks have been replaced to use Promise instead.
  3. You could iterate the result of List operations by using the PagedAsyncIterableIterator interface, compared with in previous model, you have to make a new request using the link to the next page.
  4. Interface and API change for long-running operations: To check the final result of the Poller object returned by long-running operations like beginCreateOrUpdate, please use pollUntilDone instead of pollUntilFinished. To get the final result directly, use the method with the suffix AndWait e.g.beginCreateOrUpdateAndWait.
  5. The SDK only supports ECMAScript 2015 (ES6) and beyond, all projects that referenced this SDK should be upgraded to use ES6.

If you have an existing application that uses the JavaScript/TypeScript Azure SDK packages and you're interested in updating your application to use the next-generation SDKs, here are the things that you need to do for the migration:

Authentication

In the next-generation JavaScript/TypeScript packages, we only support using @azure/identity to do the Authentication. We have deprecated the authentication methods defined in @azure/ms-rest-nodeauth and @azure/ms-rest-browserauth. If you are still using them, please follow the below example to do the migration.

Replace loginWithServicePrincipalSecret method in @azure/ms-rest-nodeauth by ClientSecretCredential in @azure/identity to get the credential.

change

import * as msRestNodeAuth from "@azure/ms-rest-nodeauth";
const credentials = msRestNodeAuth.loginWithServicePrincipalSecret(
  clientId,
  clientSecret,
  tenantId
);

into

import { ClientSecretCredential } from "@azure/identity";
const credentials = new ClientSecretCredential(tenantId, clientId, clientSecrat);

Please refer to @azure/identity for more details about @azure/identity and migration guide from @azure/ms-rest-nodeauth to @azure/identity on how to migrate from @azure/ms-rest-nodeauth.

Callbacks

In current libraries, we have some operations that allow customers to use callback such as

Current Libraries Next Generation
getInstanceView(
  resourceGroupName: string,
  cloudServiceName: string,
  options?: msRest.RequestOptionsBase
): Promise<Models.CloudServicesGetInstanceViewResponse>
      
getInstanceView(
  resourceGroupName: string,
  cloudServiceName: string,
  callback: msRest.ServiceCallback<Models.CloudServiceInstanceView>
): void;
      
getInstanceView(
  resourceGroupName: string,
  cloudServiceName: string,
  options: msRest.RequestOptionsBase,
  callback: msRest.ServiceCallback<Models.CloudServiceInstanceView>
): void;
      
getInstanceView(
  resourceGroupName: string,
  cloudServiceName: string,
  options?: msRest.RequestOptionsBase |
              msRest.ServiceCallback<Models.CloudServiceInstanceView>,
  callback?: msRest.ServiceCallback<Models.CloudServiceInstanceView>
): Promise<Models.CloudServicesGetInstanceViewResponse>
      
getInstanceView(
  resourceGroupName: string,
  cloudServiceName: string,
  options?: CloudServicesGetInstanceViewOptionalParams
): Promise<CloudServicesGetInstanceViewResponse>
      

Now, we have removed these operations that allows callback as a parameter, if you are using something like

const callback = function handle(...args) {
  // callback function body
};
getInstanceView(resourceGroupName, cloudServiceName, callback);

You may change it into a promise based

const callback = function handle(...args) {
  // callback function body
};
getInstanceView(resourceGroupName, cloudServiceName).then(...(args) => handle(...args));

List Operations

List operations now return an iterable result that follows the PagedAsyncIterableIterator interface as opposed to the previous model where you had to make a new request using the link to the next page.
The below example shows how you could handle the list result in previous version:

await client.availabilitySets.list(this.resourceName).then((response) => handle(response));

Now, you will get a iterator, and you need to do the iteration to get the result.

const result = client.availabilitySets.list(this.resourceName);
for await (const item of result) {
  handle(item);
}

The newly added PagedAsyncIterableIterator also allows you to get these items by page if the List operation result is too long.

const result = client.availabilitySets.list(this.resourceName);
for await (const item of result.byPage({ maxPageSize: 2 })) {
  handle(item);
}

Refer to @azure/core-paging for more details.

Long Running Operations

Many operations may take a long time to finish before receiving the desired response. The SDK provides two types of methods to interact with such operations. First type is a method that simply returns the result after the operation finishes processing and those methods' names correspond to the name of the API they call. One issue with these methods is that they do not provide a way to check on the current status of the operation or to access any partial results computed so far. The next-generation SDK provides similar methods but with a slightly different name, it has the prefix begin and the postfix AndWait. The other type of methods is one that returns a poller object which gives you access to the underlying state of the operation. Previously, these methods returned an object of type LROPoller, a class that is exported by @azure/ms-rest-azure-js but the new operations return an object that implements the PollerLike interface instead which is exported by @azure/core-lro. The name of those methods did not change, both versions use the prefix begin with no postfix.

Operations that return a poller.

Current Libraries Next Generation
  beginCreateOrUpdate(
    resourceGroupName: string,
    cloudServiceName: string,
    options?: Models.CloudServicesBeginCreateOrUpdateOptionalParams
  ): Promise<msRestAzure.LROPoller>
      
  async beginCreateOrUpdate(
    resourceGroupName: string,
    cloudServiceName: string,
    options?: CloudServicesCreateOrUpdateOptionalParams
  ): Promise<PollerLike<
        PollOperationState<CloudServicesCreateOrUpdateResponse>,
        CloudServicesCreateOrUpdateResponse
      >
    >
      

Operations that will poll until finish and return the result directly

Current Libraries Next Generation
  createOrUpdate(
    resourceGroupName: string,
    cloudServiceName: string,
    options?: Models.CloudServicesCreateOrUpdateOptionalParams
  ): Promise<Models.CloudServicesCreateOrUpdateResponse>
      
  async beginCreateOrUpdateAndWait(
    resourceGroupName: string,
    cloudServiceName: string,
    options?: CloudServicesCreateOrUpdateOptionalParams
  ): Promise<CloudServicesCreateOrUpdateResponse>
      

The following table compares LROPoller and PollerLike:

operation LROPOller PollerLike
return final results pollUntilFinished() pollUntilDone()
poll poll() poll()
access the current state after receiving the response of each poll request N/A onProgress()
check whether the operation finished isFinished() / isFinalStatusAcceptable() isDone()
stop polling N/A stopPolling()
check if the polling stopped N/A isStopped()
cancel the operation N/A cancelOperation()
get the current operation state getPollState() getOperationState()
access the final result getOperationResponse() getResult()
serialize the poller state N/A toString()
get the most recent response getMostRecentResponse() can be accessed using the onResponse callback in the operation options
get the current operation status getOperationStatus() can be accessed using the onResponse callback in the operation options

And here are examples of how to commonly use one of the beginCreateOrUpdateAndWait LROs found in @azure/compute:

Operations that returns a poller.

Current Libraries Next Generation
const computeClient = new compute.ComputeManagementClient(credential, subscriptionId);
const poller = await computeClient.dedicatedHosts.beginCreateOrUpdate(
  resourceGroupName,
  hostGroupName,
  hostName,
  parameter
);
console.log(`The current status? ${poller.getPollState().state"}`)
const result = await poller.pollUntilFinished().then((response) => {
  console.log(response);
});
      
const computeClient = new compute.ComputeManagementClient(credential, subscriptionId);
const poller = await computeClient.dedicatedHosts.beginCreateOrUpdate(
  resourceGroupName,
  hostGroupName,
  hostName,
  parameter
);
poller.onProgress((state) => {
  console.log(`Are we done yet? ${Boolean(state.isCompleted)});
})
const result = await poller.pollUntilDone().then((response) => {
  console.log(response);
});
      

Operations that will poll until finish and return the result directly

Current Libraries Next Generation
const computeClient = new compute.ComputeManagementClient(credential, subscriptionId);
await computeClient.dedicatedHosts
  .createOrUpdate(resourceGroupName, hostGroupName, hostName, parameter)
  .then((response) => {
    console.log(response);
  });
      
const computeClient = new compute.ComputeManagementClient(credential, subscriptionId);
await computeClient.dedicatedHosts
  .beginCreateOrUpdateAndWait(resourceGroupName, hostGroupName, hostName, parameter)
  .then((response) => {
    console.log(response);
  });
      

Please refer to @azure/core-lro for more details.

Additional Samples

We also provide some samples here for customers on how to use the next generation of Azure JavaScript/TypeScript management libraries.

Need help

If you have encountered an issue during migration, please file an issue via Github Issues and make sure you add the 'Preview' label to the issue.