Skip to main content

SDK for TypeScript

The SDK for TypeScript provides a TypeScript API for Dynatrace platform services and Dynatrace AppEngine functionality.

It consists of the following:

  • TypeScript packages focused on specific use cases to use Dynatrace platform functionality.
  • Modular clients for each Dynatrace platform service to reduce overhead on a specific use.

Using the SDK for Dynatrace app development

Generic layer

This layer of the SDK can be used in all TypeScript apps, providing a use case-based approach for Dynatrace app developers and for writing scripts in Dynatrace Workflows and Dynatrace Notebooks.

Here is an example of how to format a number to a human-readable string in a Dynatrace function:

import { format, units } from '@dynatrace-sdk/units';

export default async function () {
const value = 1200;
const displayValue = format(value, {
input: units.data.byte,
});
return displayValue; // returns "1.17 KiB"
}

Low-level clients

Client packages give you direct access to Dynatrace platform services. These reflect the services API and provide you with granular use of the services. The requests have authentication with the user's permissions on the respective environment.

The following example loads the connected ActiveGates matching network zone lab:

import { activeGatesClient } from '@dynatrace-sdk/client-classic-environment-v2';

export default async function () {
const activeGates = await activeGatesClient.getAllActiveGates({
networkZone: 'lab',
});
// …
}
Note

Your app needs to declare scopes for the services it uses to improve security. Please find the necessary scope in the reference for each client.

Using the SDK in ad-hoc functions

You can use the SDK for TypeScript in ad-hoc functions in Dynatrace Workflows and Dynatrace Notebooks, which applies to all convenience packages (except UI-related ones) and low-level clients.

Following is an example of how to ingest metrics in a workflow:

import { metricsClient } from '@dynatrace-sdk/client-classic-environment-v2';

export default async function () {
return metricsClient.ingest({ body: 'cpu.temperature,hostname=hostA,cpu=1 55' });
}

Error handling

Note

Before implementing error handling, consider if it's necessary. To learn more, visit best practices.

You should use the try...catch block to properly handle errors that may occur using clients. Within the try block, wrap the awaited function call, which might throw an error to catch any exceptions.

import { activeGatesClient } from '@dynatrace-sdk/client-classic-environment-v2';

export default async function () {
try {
const activeGates = await activeGatesClient.getAllActiveGates({
networkZone: 'lab',
});
} catch (error: unknown) {
// Perform additional error-handling tasks
// Or: Rethrow the error to propagate it further up the call stack
// throw error;
}
// …
}

Type guards

For every error a client can throw, clients export the type guard functions that help narrow down the type of error within a specific code block, allowing for more accurate and reliable type inference.

To check which errors a client function can throw, consult the client's reference docs.

Additionally, there is a set of errors and their type guards that are common for every client that's also exported:

  • ClientRequestError - This is a base class for all HTTP errors and is also thrown when an unexpected response code is received.
  • ApiGatewayError - This error can occur for various reasons, such as incorrect configurations, authentication issues, or problems with the backend integration.
  • InvalidResponseError - This may occur when the response received from the service doesn't match the client schema.
  • ApiClientError - A base error class in the client SDKs. All other error classes derive from it.
import { directSharesClient, isShareNotFound, isClientRequestError } from '@dynatrace-sdk/client-document';

try {
const activeGates = await directSharesClient.getDirectShare({
shareId: '...',
});
} catch (error: unknown) {
if (isShareNotFound(error)) {
/* error: ShareNotFound */
return;
}
if (isClientRequestError(error)) {
/* error: ClientRequestError */
}
throw error;
}
Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Best practices

  • Decide whether to handle - apps should only handle errors that they can provide a meaningful error state for or errors that the user can potentially self-resolve. If the app can provide a clear error message or state that guides the user towards resolving the issue on their own, it can enhance the user experience. However, we advise rethrowing unhandled errors if the error is beyond the app's scope or the user's ability to resolve it. Striking a balance between empowering users to address certain errors independently and acknowledging self-resolution limitations can contribute to a smoother and more user-friendly app experience.
  • All unhandled errors should be rethrown to be detected by a real user monitoring agent.
  • Treat all errors as unknown. unknown enforces type checking and requires explicit type assertions or type narrowing before using the value. It's recommended to use unknown over any when dealing with values of unknown types to maintain type safety in your TypeScript code.

Giving feedback

We at Dynatrace dedicate ourselves to providing the best possible experience for our users. To achieve this, we would like your feedback on our SDK. Your feedback will help us improve our product's quality and ensure that we meet your needs. The Dynatrace community is a welcoming place to share your thoughts, make requests, and upvote topics related to SDK improvements. Join the discussion.

Discover the packages

Still have questions?
Find answers in the Dynatrace Community