Skip to content

Latest commit

 

History

History
75 lines (43 loc) · 7.08 KB

File metadata and controls

75 lines (43 loc) · 7.08 KB

Azure Core 2.0 for JS SDKs

What do you mean 2.0?

Today, in Azure SDKs for JS, one of the primary core packages we ship is @azure/core-http. This package forms the runtime for all the auto-generated Azure SDKs by providing the mechanism to route HTTP requests through a pipeline made of different policies such as retry, logging, and tracing. As of this document being written it sits at version 1.1.5. Due to a number factors discussed in this document, there is a desire to create a new major version of this package (i.e. "2.0.0") that would include breaking changes.

Azure customers are indirect consumers of this package via the SDKs for different Azure services. Therefore, a major version change would not be largely disruptive. Currently, in order to preserve compatibility and not complicate the story for servicing, a new package has been created that is named @azure/core-rest-pipeline.

History, Context, and Motivations

In ancient times (~5 years ago), Microsoft provided SDKs for NodeJS developers wanting to interact with Azure services. Ultimately, many of these packages were generated using AutoRest using a package called autorest.nodejs. The autogenerated code had the need for a common, re-usable core for performing HTTP operations, and thus ms-rest was created.

Another package ms-rest-azure was created to house Azure-specific components and authetication code that worked with a variety of credentials like Service Principal, Device Token, and Managed Identity. At this point, support for TypeScript came in the form of hand-authored type declaration files.

Later, there emerged a desire for isomorphic packages, packages that worked in both the browser as well as Node. This required a new runtime, code generator and repo. As part of this effort,

  • ms-rest became @azure/ms-rest-js to provide the same capabilities in both Node.js and browser
  • The authentication pieces from ms-rest-azure were put into @azure/ms-rest-nodeauth and an equivalent package was created for the browser called @azure/ms-rest-browserauth.
  • All remaining parts of ms-rest-azure were placed into @azure/ms-rest-azure-js.
  • The new code generator (autorest.typescript) that generated code in TypeScript and used the newer runtimes mentioned above replaced the existing one (autorest.nodejs) that generated JavaScript code.
  • The packages thus generated got a new home in the repo azure-sdk-for-js. The older packages lived in azure-sdk-for-node repo.

A year or so later, the new Azure SDK team was formed in Nov 2018 that then came up with guidelines on how to write an Azure SDK in TypeScript. To follow these guidelines, we needed yet another runtime. This was the new @azure/core-http package built over the existing @azure/ms-rest-js. At the time we chose to do so as making slight changes and improvements to a tried and tested solution was preferred over investing time in a solution that had to be written from scratch.

The downside is that much of the code had evolved organically over time, experienced incomplete upgrades to various layers, and had dead code that wasn't really needed anymore. We mitigated this during the 1.0 GA timeframe in Nov 2020 by manually declaring cleaner public interfaces (e.g. OperationOptions over RequestOptionsBase) but many of the internal interfaces were still messy, loosely typed, or confusing.

As the JS team has gained experience shipping track 2 client libraries, we realized that the technical debt accumulated in @azure/core-http was costing us in terms of maintainability and performance. After multiple internal discussions about what exactly needed to change in order to move forward, a plan emerged to modernize @azure/core-http and give us a more robust core to build upon.

Important goals and considerations:

  • The request pipeline should be re-usable outside of AutoRest generated code (e.g. Cosmos.)
  • The request pipeline should be easily customizable by client libraries and consumers.
  • Performance of the majority use case should be optimized and be memory efficient.
  • Future improvements to code generator should be easy to phase in.

Scope of work

Separation of Concerns

One major goal of this work is to split the library into three separate packages: @azure/core-rest-pipeline, @azure/core-client, and @azure/core-xml. This is to enable smaller dependency graphs and bundles for individual client libraries.

The first package, @azure/core-rest-pipeline will not be AutoRest-specific and is intended to be usable by any client that wants to make requests using a pipeline in a way that follows our SDK design guidelines.

@azure/core-client is intended to be a runtime dependency of any AutoRest-generated client library and has all necessary helpers except for XML (de)serialization. Packages that require XML support will additionally depend upon @azure/core-xml.

Pipeline improvements

A major weakness of the existing JS Core was that the request pipeline system was difficult to customize at the library level. This placed an undue burden on authors of libraries and increased support costs. As other languages had better support for customizing the request pipeline, we had a desire to provide a simple and flexible way to add and order policies that could affect both HTTP requests and responses.

The New Pipeline Design solves these concerns by providing a new abstraction that is able to reliably apply ordered policies with minimal configuration.

Dropping legacy browser support

As 2.0 is intended to be a modernization effort, it will not support Internet Explorer. This does mean that client libraries which need to support IE will not be able to upgrade until such time as they are not required to support legacy browsers.

There are a number of benefits to this, primarily in simplified bundled code that is much smaller. There are also performance improvements and the ability to rely on certain primitive constructs such as "Map" and "Set" without polyfills.

Cleanup and simplification

There are many small changes such as internally adopting our external interfaces (e.g. OperationOptions), letting go of unnecessary or outdated dependencies (e.g. tunnel and node-fetch), and removing API surface we no longer wish to support (e.g. URLBuilder.)

By performing this cleanup now, we can reduce our overhead and ensure that we are able to be more agile when making improvements to the request pipeline in the future.

Work item / issue tracking

All work is tracked in Azure/azure-sdk-for-js#8535

Future Work

Beyond the direct benefits of performing the work detailed in this document, we believe it will enable us to complete several other long-desired projects such as:

  • Moving @azure/cosmos to use our standard request pipeline
  • Improving and simplifying codegen for response serialization/deserialization
  • Generating more of the convenience layer
  • Reducing our overhead per service call