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
.
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 inazure-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.
- 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.
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
.
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.
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.
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.
All work is tracked in Azure/azure-sdk-for-js#8535
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