Learn how to set up and use the TypeScript SDK.
This step-by-step guide leads you through setting up and making API calls using the TypeScript SDK.
Requirements
To follow this guide you should have the following:
- A commercetools Composable Commerce Project
- An API Client
- Node v18.17.x (or later)
- Either
npm
v9.6.x (or later) oryarn
v3.2.x (or later)
Objectives of the get started guide
After following this guide, you will have:
Placeholder values
Example code in this guide uses the following placeholder values. You should replace these placeholders with the following values.
Placeholder | Replace with | From |
---|---|---|
{projectKey} | project_key | your API Client |
{clientID} | client_id | your API Client |
{clientSecret} | secret | your API Client |
{scope} | scope | your API Client |
{region} | your Region | Hosts |
Install the TypeScript SDK
Use the following command to install the SDK Client:
npm install @commercetools/ts-client
# or
yarn add @commercetools/ts-client
For HTTP API
For Import API
For Audit Log API
For Checkout API
npm install @commercetools/platform-sdk
# or
yarn add @commercetools/platform-sdk
Create the client
BuildClient.ts
and insert the following code. This code contains your API Client configuration, API-specific HttpMiddlewareOptions
configuration, and then exports the ClientBuilder
with the specified middleware.For HTTP API
For Import API
For Audit Log API
For Checkout API
import {
ClientBuilder,
// Import middlewares
type AuthMiddlewareOptions, // Required for auth
type HttpMiddlewareOptions, // Required for sending HTTP requests
} from '@commercetools/ts-client';
export const projectKey = '{projectKey}';
const scopes = ['{scope}'];
// Configure authMiddlewareOptions
const authMiddlewareOptions: AuthMiddlewareOptions = {
host: 'https://auth.{region}.commercetools.com',
projectKey,
credentials: {
clientId: '{clientID}',
clientSecret: '{clientSecret}',
},
scopes,
httpClient: fetch,
};
// Configure HTTP API httpMiddlewareOptions
const httpAPIHTTPMiddlewareOptions: HttpMiddlewareOptions = {
host: 'https://api.{region}.commercetools.com',
httpClient: fetch,
};
// Export the ClientBuilder for the HTTP API
export const ctpClientHTTPAPI = new ClientBuilder()
.withProjectKey(projectKey)
.withClientCredentialsFlow(authMiddlewareOptions)
.withHttpMiddleware(httpAPIHTTPMiddlewareOptions)
.withLoggerMiddleware() // Include middleware for logging
.build();
Add middleware
withClientCredentialsFlow
) and HttpMiddleware authMiddlewareOptions
, httpMiddlewareOptions
, and withLoggerMiddleware
to handle auth, API requests, and logging respectively.ClientBuilder
with method chaining.
Test the client
ApiRoot
from the client. The code also contains test calls which outputs to the log.For HTTP API
For Import API
For Audit Log API
For Checkout API
import { ctpClientHTTPAPI, projectKey } from './BuildClient';
import {
createApiBuilderFromCtpClient,
Project,
} from '@commercetools/platform-sdk';
const httpApiRoot = createApiBuilderFromCtpClient(
ctpClientHTTPAPI
).withProjectKey({
projectKey,
});
// Example call to return Project information
// This code has the same effect as sending a GET request to the commercetools Composable Commerce API without any endpoints.
async function getProject(): Promise<Project> {
const response = await httpApiRoot.get().execute();
return response.body;
}
// Retrieve Project information and output the result to the log
await getProject().then(console.log).catch(console.error);
httpApiRoot
to build requests to the HTTP API.createApiBuilderFromCtpClient
function accepts an optional second argument called baseUri
, which is of type string.
You can use this argument to override the host parameters in httpMiddlewareOptions
.createApiBuilderFromCtpClient(client: Client, baseUri?: string): ApiRoot;
Use the TypeScript SDK
Imports
Without importing resource-specific packages and interfaces you cannot use/access specific objects and methods.
ShoppingList
and ShoppingListDraft
interfaces from the @commercetools/platform-sdk
package.import { ShoppingList, ShoppingListDraft } from '@commercetools/platform-sdk';
Asset
interface. Always use API-specific resources to avoid errors and conflicts.Create objects
Unlike other SDKs which use builders to construct drafts, update actions, and other objects/types that contain multiple fields, the TypeScript SDK uses standard TypeScript objects.
import {
LocalizedString,
Money,
CategoryDraft,
} from '@commercetools/platform-sdk';
// Create a LocalizedString
const multiLanguageString: LocalizedString = {
en: 'English value',
de: 'German value',
};
// Create US$100.00
const money: Money = {
currencyCode: 'USD',
centAmount: 10000,
type: 'centPrecision',
};
// Create a CategoryDraft
const categoryDraft: CategoryDraft = {
name: { en: 'English name' },
slug: { en: 'english-slug' },
key: 'category-key',
};
Structure your API call
The following examples demonstrate how to structure calls to the HTTP API using the TypeScript SDK. The examples use the Shopping Lists endpoint, but the structure is identical for most other endpoints in the HTTP API.
Using the Import API, Audit Log API, or Checkout API may differ slightly, but the structure of building requests remains the same.
Add an endpoint
httpApiRoot
. The following targets the Shopping Lists endpoint:const shoppingListsRequest = await httpApiRoot.shoppingLists();
shoppingLists()
to any other endpoint, for example products()
, categories()
, or customers()
. If you do not specify an endpoint when using httpApiRoot
, the SDK references the Project.Retrieve data
Get a single resource
.get()
and .execute()
.async function getShoppingListById(ID: string): Promise<ShoppingList> {
const response = await httpApiRoot
.shoppingLists()
.withId({ ID })
.get()
.execute();
return response.body;
}
await getShoppingListById('a-shoppinglist-id')
.then(console.log)
.catch(console.error);
async function getShoppingListByKey(key: string): Promise<ShoppingList> {
const response = await httpApiRoot
.shoppingLists()
.withKey({ key })
.get()
.execute();
return response.body;
}
await getShoppingListByKey('a-shoppinglist-key')
.then(console.log)
.catch(console.error);
Get multiple resources
get()
, the endpoint returns a PagedQueryResponse
, which is identical to PagedQueryResult in the HTTP API.async function getShoppingLists(): Promise<ShoppingListPagedQueryResponse> {
const response = await httpApiRoot.shoppingLists().get().execute();
return response.body;
}
await getShoppingLists().then(console.log).catch(console.error);
get()
method. Within queryArgs
you can define where
, sort
, expand
, limit
, and/or offset
async function getShoppingLists(): Promise<ShoppingListPagedQueryResponse> {
const response = await httpApiRoot
.shoppingLists()
.get({
queryArgs: {
where: ['lineItems is not empty'],
sort: 'name.en-US desc',
expand: ['customer'],
limit: 5,
offset: 0,
},
})
.execute();
return response.body;
}
View results
PagedQueryResponse
has a property called results
, which contains an array of the returned resources. In this case, Shopping Lists.const shoppingLists = await getShoppingLists();
shoppingLists.results.forEach((sl) => {
console.log(`Shopping List Name: ${sl.name['en-US']}`);
console.log(`Shopping List ID: ${sl.id}`);
});
Write a resource
Create a new resource
const newShoppingListDetails: ShoppingListDraft = {
key: 'shopping-list-key',
name: { 'en-US': 'English name of Shopping List' },
description: { 'en-US': 'Description of Shopping List' },
//customer: { typeId: 'customer', id: 'customer-id' }, // Optional association with a customer
};
/**Post the ShoppingListDraft and get the new Shopping List*/
async function createShoppingList(
body: ShoppingListDraft
): Promise<ShoppingList> {
const response = await httpApiRoot.shoppingLists().post({ body }).execute();
return response.body;
}
await createShoppingList(newShoppingListDetails)
.then(console.log)
.catch(console.error);
Update an existing resource
ShoppingListUpdate
) contains a collection of update actions and the last seen version of the resource./**The `setKey` update action for Shopping Lists */
const setShoppingListKey: ShoppingListSetKeyAction = {
action: 'setKey',
key: 'a-new-shoppinglist-key',
};
/**A ShoppingListUpdate containing the `setKey` action */
const shoppingListUpdate: ShoppingListUpdate = {
version: 1,
actions: [setShoppingListKey], // You can add more actions to this array to perform multiple updates in one request
};
/**Update an existing Shopping List by its ID */
async function updateShoppingList(
ID: string,
body: ShoppingListUpdate
): Promise<ShoppingList> {
const response = await httpApiRoot
.shoppingLists()
.withId({ ID })
.post({ body })
.execute();
return response.body;
}
await updateShoppingList('{shoppingListID}', shoppingListUpdate)
.then(console.log)
.catch(console.error);
Delete a resource
.delete()
method with the last seen version of the resource. You must identify the resource to delete using withId()
or withKey()
.async function deleteShoppingList(ID: string, version: number) {
const response = await httpApiRoot
.shoppingLists()
.withId({ ID })
.delete({ queryArgs: { version } })
.execute();
return response.body;
}
await deleteShoppingList('{shoppingListID}', 1)
.then(console.log)
.catch(console.error);
Use the TypeScript SDK in the browser
You can use the TypeScript SDK as an embedded Universal Module Definition (UMD) module or an imported package in a frontend framework/library such as React.
As an embedded UMD module
Create an HTML file and insert the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>TypeScript SDK Examples</title>
<script src="https://unpkg.com/browse/@commercetools/ts-client@latest/dist/commercetools-ts-client.umd.js"></script>
<script src="https://unpkg.com/@commercetools/platform-sdk@latest/dist/commercetools-platform-sdk.umd.js"></script>
</head>
<body>
<!-- Click this button to return the Project details -->
<p>
<button onclick="getProjectDetails()">Get Project Information</button>
</p>
<!-- This text is overwritten when getProjectDetails() finishes -->
<p id="details">
Click the above button to display the Project information.
</p>
</body>
<script>
// Enter your API client configuration
var oauthUri = 'https://auth.{region}.commercetools.com';
var baseUri = 'https://api.{region}.commercetools.com';
var credentials = {
clientId: '{clientID}',
clientSecret: '{clientSecret}',
};
var projectKey = '{projectKey}';
// Builds the client
var { ClientBuilder } = window['@commercetools/ts-client'];
var client = new ClientBuilder()
.defaultClient(baseUri, credentials, oauthUri, projectKey)
.build();
var { createApiBuilderFromCtpClient } =
window['@commercetools/platform-sdk'];
var httpApiRoot = createApiBuilderFromCtpClient(client).withProjectKey({
projectKey,
});
// Returns the Project details
function getProjectDetails() {
httpApiRoot
.get()
.execute()
.then(function ({ body }) {
window.document.getElementById('details').innerHTML =
JSON.stringify(body);
});
}
</script>
</html>
When loaded in your web browser this page displays a button that, when clicked, returns your Project information.
getProjectDetails()
function is similar to code examples within this get started guide. Consult the previous code examples to add further functionality to the HTML document.As an imported package
App.tsx
file.import React, { useState, useEffect } from 'react';
import { ClientBuilder, type Client } from '@commercetools/ts-client';
import {
createApiBuilderFromCtpClient,
ApiRoot,
} from '@commercetools/platform-sdk';
const BASE_URI = 'https://api.{region}.commercetools.com';
const OAUTH_URI = 'https://auth.{region}.commercetools.com';
const PROJECT_KEY = '{projectKey}';
const CREDENTIALS = {
clientId: '{clientID}',
clientSecret: '{clientSecret}',
};
export function App() {
const [projectDetails, setProjectDetails] = useState({});
// Create client
const getClient = (): Client => {
return new ClientBuilder()
.defaultClient(BASE_URI, CREDENTIALS, OAUTH_URI, PROJECT_KEY)
.build();
};
// Get apiRoot
const getApiRoot = (client: Client): ApiRoot => {
return createApiBuilderFromCtpClient(client);
};
useEffect(function () {
const client = getClient();
const httpApiRoot = getApiRoot(client);
httpApiRoot
.withProjectKey({ projectKey: PROJECT_KEY })
.get()
.execute()
.then(({ body }) => {
setProjectDetails(body);
})
.catch(console.error);
}, []);
return (
<div>
<h2>Project details for {PROJECT_KEY}:</h2>
<pre>{JSON.stringify(projectDetails, null, 2)}</pre>
</div>
);
}