14 May 2024

Migrating to the new APS Node.js SDK

Default blog image

At the end of 2023 we announced the new Node.js/TypeScript SDK for Autodesk Platform Services. While the project is still in beta, it is unlikely that the public facing interfaces would be undergoing any dramatic changes anymore, so this is a good time to take a look at how you could migrate your Node.js applications to this new official SDK.

Packaging & Installation

The SDK is split into separate NPM packages for individual APIs, for example:

There's also a "manager" module - @aps_sdk/autodesk-sdkmanager - that provides shared functionality and configuration (e.g., for authentication, resiliency, or logging) for all the individual API modules.

Tip: you can find the complete list of modules available as part of this SDK on https://www.npmjs.com/~aps.sdk.

When adding these dependencies to your project, simply install the SDK manager and the APIs you need using your favorite Node.js package manager, for example:

npm install --save @aps_sdk/autodesk-sdkmanager @aps_sdk/authentication @aps_sdk/oss @aps_sdk/model-derivative

Initialization

Each API module exposes a *Client class - for example, AuthenticationClient or OssClient - that will be your entrypoint to the corresponding APS service. Constructors of all these classes expect an instance of the SDK manager as their only parameter. Here's an example of how you would initialize some of these clients in your code:

const { SdkManagerBuilder } = require("@aps_sdk/autodesk-sdkmanager");
const { AuthenticationClient } = require("@aps_sdk/authentication");
const { OssClient } = require("@aps_sdk/oss");
const { ModelDerivativeClient } = require("@aps_sdk/model-derivative");

const sdkManager = SdkManagerBuilder.create().build();
const authenticationClient = new AuthenticationClient(sdkManager);
const ossClient = new OssClient(sdkManager);
const modelDerivativeClient = new ModelDerivativeClient(sdkManager);

The SDK supports ES6 modules as well:

import { SdkManagerBuilder } from "@aps_sdk/autodesk-sdkmanager";
import { AuthenticationClient } from "@aps_sdk/authentication";
import { OssClient } from "@aps_sdk/oss";
import { ModelDerivativeClient } from "@aps_sdk/model-derivative";

const sdkManager = SdkManagerBuilder.create().build();
const authenticationClient = new AuthenticationClient(sdkManager);
const ossClient = new OssClient(sdkManager);
const modelDerivativeClient = new ModelDerivativeClient(sdkManager);

Authentication & User Info

Generating 2-legged tokens:

// ...

import { AuthenticationClient, Scopes } from "@aps_sdk/authentication";

// ...

const twoLeggedCredentials = await authenticationClient.getTwoLeggedToken(APS_CLIENT_ID, APS_CLIENT_SECRET, [Scopes.DataRead, Scopes.ViewablesRead]); 
console.log(twoLeggedCredentials.access_token);

Generating and refreshing 3-legged tokens is very similar to how it was done using the old/legacy SDK:

// ...

import { AuthenticationClient, ResponseType, Scopes } from "@aps_sdk/authentication";

// Generating the authorization URL
const url = authenticationClient.authorize(APS_CLIENT_ID, ResponseType.Code, APS_CALLBACK_URL, [Scopes.DataRead, Scopes.ViewablesRead]);
console.log(url);

// Exchanging temporary code for an access token
const threeLeggedCredentials = await authenticationClient.getThreeLeggedToken(APS_CLIENT_ID, temporaryCode, APS_CALLBACK_URL, {
    clientSecret: APS_CLIENT_SECRET
});
console.log(threeLeggedCredentials.access_token);

// Refreshing an access token
const refreshedCredentials = await authenticationClient.getRefreshToken(APS_CLIENT_ID, threeLeggedCredentials.refresh_token, {
    clientSecret: APS_CLIENT_SECRET,
    scopes: [Scopes.ViewablesRead]
});
console.log(refreshedCredentials.access_token);

Finally, here's how you would extract user information from an existing 3-legged token:

const userInfo = await authenticationClient.getUserInfo(threeLeggedCredentials.access_token);
console.log(userInfo.name);

Note: in v2 of the Authentication API, the firstName and lastName fields have been replaced by a single field called name.

Error Checking

Under the hood the SDK uses axios for all its HTTP requests. Whenever the SDK throws an exception, the error object will include axios-specific information under err.axiosError. This might come in handy in certain scenarios, for example, when you're expecting a non-2XX response from an API call:

try {
    await ossClient.getBucketDetails(accessToken, bucketKey);
    console.log("Bucket exists");
} catch (err) {
    if (err.axiosError.response.status === 404) {
        console.log("Bucket does not exist");
    } else {
        throw err;  
    }
}

Convenience Methods

In certain cases the API clients may expose convenience methods that combine two or more API requests into a single method call. For example, when uploading files to an OSS bucket, instead of creating an upload URL, manually uploading the content, and finally sending a request to complete the upload, you can simply call await ossClient.upload(APS_BUCKET, objectName, localFilePath, accessToken). We're currently setting up a documentation and a changelog for the SDK project, and we'll highlight these options there.

Additional Resources

Before the official documentation for the new SDKs is ready, you can learn more about its usage by checking out the samples (part of the project's GitHub repository: https://github.com/autodesk-platform-services/aps-sdk-node), or our tutorials: https://tutorials.autodesk.io.

Related Article