Get started with the Java SDK

Learn how to set up and use the Java SDK.

This step-by-step guide leads you through setting up and making API calls using the Java SDK.

Requirements

To follow this guide you should have the following:

  • A commercetools Composable Commerce Project
  • An API Client
  • Java 8 (or later)
For more information on setting up a commercetools Composable Commerce Project or API Client, follow our Getting started with commercetools Composable Commerce guides.

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.

If you do not have an API Client, follow our Get your API Client guide.
PlaceholderReplace withFrom
{projectKey}project_keyyour API Client
{clientID}client_idyour API Client
{clientSecret}secretyour API Client
{scope}scopeyour API Client
{region}your RegionHosts

Install the Java SDK

Gradle

Add the following to your build.gradle file.
The following example installs the latest version of each dependency. To use a specific version, replace latest.release with the version number.
 ext {
     versions = [
         commercetools: "latest.release"
     ]
 }

 repositories {
     mavenCentral()
 }

 dependencies {
     implementation "com.commercetools.sdk:commercetools-http-client:${versions.commercetools}"
     implementation "com.commercetools.sdk:commercetools-sdk-java-api:${versions.commercetools}"
 }
To access the Import API, Audit Log API, or Checkout API, include the respective dependency:

For Import API

For Audit Log API

For Checkout API

implementation "com.commercetools.sdk:commercetools-sdk-java-importapi:${versions.commercetools}"
implementation "com.commercetools.sdk:commercetools-sdk-java-history:${versions.commercetools}"
implementation "com.commercetools.sdk:commercetools-sdk-java-checkout:${versions.commercetools}"

Maven

Add the following to your pom.xml file.
The following example installs the latest version of each dependency. To use a specific version, replace LATEST with the version number.
 <properties>
     <commercetools.version>LATEST</commercetools.version>
 </properties>

 <dependencies>
     <dependency>
       <groupId>com.commercetools.sdk</groupId>
       <artifactId>commercetools-http-client</artifactId>
       <version>${commercetools.version}</version>
     </dependency>
     <dependency>
       <groupId>com.commercetools.sdk</groupId>
       <artifactId>commercetools-sdk-java-api</artifactId>
       <version>${commercetools.version}</version>
 </dependencies>
To access the Import API, Audit Log API, or Checkout API, include the respective dependency:

For Import API

For Audit Log API

For Checkout API

<dependency>
  <groupId>com.commercetools.sdk</groupId>
  <artifactId>commercetools-sdk-java-importapi</artifactId>
  <version>${commercetools.version}</version>
</dependency>
<dependency>
  <groupId>com.commercetools.sdk</groupId>
  <artifactId>commercetools-sdk-java-history</artifactId>
  <version>${commercetools.version}</version>
</dependency>
<dependency>
  <groupId>com.commercetools.sdk</groupId>
  <artifactId>commercetools-sdk-java-checkout</artifactId>
  <version>${commercetools.version}</version>
</dependency>

Maven Central

For any SDK module, you must install an HTTP client module. The default HTTP client module is commercetools-http-client.

Troubleshoot with the Spring Framework

The Spring Framework has an optional dependency to OkHttp in version 3.x.

To avoid problems use the commercetools-okhttp-client3 or commercetools-apachehttp-client module instead of the module commercetools-http-client.

Create the Client class

Create a class called Client and add the following code:

For HTTP API

For Import API

For Audit Log API

For Checkout API

// Package declaration

// Required imports
import com.commercetools.api.client.ProjectApiRoot;
import com.commercetools.api.defaultconfig.ApiRootBuilder;
import com.commercetools.api.defaultconfig.ServiceRegion;
import io.vrap.rmf.base.client.oauth2.ClientCredentials;

public class HTTPApiClient {

    public static ProjectApiRoot createApiClient() {
          final ProjectApiRoot httpApiRoot = ApiRootBuilder.of()
            .defaultClient(ClientCredentials.of()
            .withClientId("{clientID}")
            .withClientSecret("{clientSecret}")
            .build(),
            ServiceRegion.GCP_EUROPE_WEST1)
          .build("{projectKey}");

          return httpApiRoot;
      }
  }

Change ServiceRegion.GCP_EUROPE_WEST1 to match the Region where your Project is hosted. For more information about the supported values, see ServiceRegion.
// Package declaration

// Required imports
import com.commercetools.importapi.client.ProjectApiRoot;
import com.commercetools.importapi.defaultconfig.ImportApiRootBuilder;
import com.commercetools.importapi.defaultconfig.ServiceRegion;
import io.vrap.rmf.base.client.oauth2.ClientCredentials;

public class ImportApiClient {

    public static ProjectApiRoot createApiClient() {
          final ProjectApiRoot importApiRoot = ImportApiRootBuilder.of()
          .defaultClient(ClientCredentials.of()
          .withClientId("{clientID}")
          .withClientSecret("{clientSecret}")
          .build(),
  ServiceRegion.GCP_EUROPE_WEST1)
          .build("{projectKey}");

          return importApiRoot;
      }
  }

Change ServiceRegion.GCP_EUROPE_WEST1 to match the Region where your Project is hosted. For more information about the supported values, see ServiceRegion.
// Package declaration

// Required imports
import com.commercetools.history.client.ProjectApiRoot;
import com.commercetools.history.defaultconfig.HistoryApiRootBuilder;
import com.commercetools.history.defaultconfig.ServiceRegion;
import io.vrap.rmf.base.client.oauth2.ClientCredentials;

public class HistoryApiClient {

    public static ProjectApiRoot createApiClient() {
          final ProjectApiRoot historyApiRoot = HistoryApiRootBuilder.of()
            .defaultClient(ClientCredentials.of()
            .withClientId("{clientID}")
            .withClientSecret("{clientSecret}")
            .build(),
            ServiceRegion.GCP_EUROPE_WEST1)
          .build("{projectKey}");

          return historyApiRoot;
      }
  }

Change ServiceRegion.GCP_EUROPE_WEST1 to match the Region where your Project is hosted. For more information about the supported values, see ServiceRegion.
// Package declaration

// Required imports
import com.commercetools.checkout.client.ProjectApiRoot;
import com.commercetools.checkout.defaultconfig.CheckoutApiRootBuilder;
import com.commercetools.checkout.defaultconfig.ServiceRegion;
import io.vrap.rmf.base.client.oauth2.*;

public class CheckoutApiClient {

    public static ProjectApiRoot createApiClient() {
          final ProjectApiRoot checkoutApiRoot = CheckoutApiRootBuilder.of()
          .defaultClient(ClientCredentials.of()
          .withClientId("{clientID}")
          .withClientSecret("{clientSecret}")
          .build(),
  ServiceRegion.GCP_EUROPE_WEST1)
          .build("{projectKey}");

          return checkoutApiRoot;
      }
  }

Change ServiceRegion.GCP_EUROPE_WEST1 to match the Region where your Project is hosted.

Test the Client

The following code demonstrates how to create an 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

// Required imports
import com.commercetools.api.client.ProjectApiRoot;
import com.commercetools.api.models.project.Project;

// Create httpApiRoot from your HTTPApiClient
ProjectApiRoot httpApiRoot = HTTPApiClient.createApiClient();

// Make a get call to the Project
Project myProject = httpApiRoot
  .get()
  .executeBlocking()
  .getBody();

// Output the Project name
System.out.println(myProject.getName());

You can now use the httpApiRoot to build requests to the HTTP API.
// Required imports
import com.commercetools.importapi.client.ProjectApiRoot;
import com.commercetools.importapi.models.importcontainers.ImportContainer;

// Create importApiRoot from your ImportApiClient
ProjectApiRoot importApiRoot = ImportApiClient.createApiClient();

// Make a get call to retrieve a list of ImportContainers
List<ImportContainer> importContainers = importApiRoot
    .importContainers()
    .get()
    .executeBlocking()
    .getBody()
    .getResults();

// Output the Import Containers
System.out.println(importContainers);

You can now use the importApiRoot to build requests to the Import API.
// Required imports
import com.commercetools.history.client.ProjectApiRoot;
import com.commercetools.history.models.change_history.RecordPagedQueryResponse;

// Create historyApiRoot from your HistoryApiClient
ProjectApiRoot historyApiRoot = HistoryApiClient.createApiClient();

// Example call to return recent Category history
RecordPagedQueryResponse getCategoryHistory = historyApiRoot
    .withResourceTypeValue("categories")
    .get()
    .executeBlocking()
    .getBody();

// Output the Category history
System.out.println(getCategoryHistory);

You can now use the historyApiRoot to build requests to the Audit Log API.
// Required imports
import com.commercetools.checkout.client.ProjectApiRoot;

// Create checkoutApiRoot from your CheckoutApiClient
ProjectApiRoot checkoutApiRoot = CheckoutApiClient.createApiClient();

// Example call to get a Transaction by key
Transaction transaction = checkoutApiRoot
    .transactions()
    .withKey("a-transaction-key")
    .get()
    .executeBlocking()
    .getBody();

// Output the Transaction
System.out.println(transaction);

You can now use the checkoutApiRoot to build requests to the Checkout API.

Use the Java SDK

Imports

Without importing resource-specific packages and interfaces you cannot use/access specific objects and methods.

For example, to use or create a Shopping List you must import:

import com.commercetools.api.models.shopping_list.ShoppingList;
import com.commercetools.api.models.shopping_list.ShoppingListDraft;
Alternatively, you can include everything from the com.commercetools.api.models.shopping_list package using:
import com.commercetools.api.models.shopping_list.*;
When using the Import API, Audit Log API, or Checkout API, take care when importing resources as some resources share names in different packages. For example, the HTTP API, Import API, and Audit Log API all have an Asset interface. Always use API-specific resources to avoid errors and conflicts.
You can find a list of the available packages to import in the Javadoc.

Create objects

The Java SDK follows a builder pattern to construct drafts, update actions, and other objects/types that contain multiple fields.

// Create a LocalizedString
LocalizedString multiLanguageString = LocalizedString
  .builder()
  .addValue("en", "English value")
  .addValue("de", "German value")
  .build();

// Create US$100.00
Money money = Money.builder().currencyCode("USD").centAmount(10000l).build();

// Create a CategoryDraft
CategoryDraft categoryDraft = CategoryDraft
  .builder()
  .name(LocalizedString.ofEnglish("english name"))
  .slug(stringBuilder -> stringBuilder.addValue("en", "english-slug"))
  .key("category-key")
  .build();
After you add the fields and values, .build() finishes building the object.
Consult the API reference for the HTTP API, Import API, Audit Log API, and Checkout API to ensure that you include all required fields.

Structure your API call

The following examples demonstrate how to structure calls to the HTTP API using the Java 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.

Calls to the Java SDK require you to make an instance of the type you want returned, or an instance of an action to take:

// Return the information of a specific Shopping List
ShoppingList shoppingListInfo
// ...

// Return all Shopping Lists
ShoppingListPagedQueryResponse allShoppingLists
// ...

// Create an update action for setting a Shopping List key
ShoppingListSetKeyAction shoppingListSetKeyAction
// ...

Retrieve data

When retrieving, include the httpApiRoot and the associated endpoint.
// Get information of a specific Shopping List
ShoppingList shoppingListInfo = httpApiRoot
.shoppingLists()
// ...

// Return all Shopping Lists
ShoppingListPagedQueryResponse allShoppingLists = httpApiRoot
.shoppingLists()
// ...

Get a single resource

When getting a specific resource, you should include its ID or key followed by .get(), .executeBlocking() and .getBody();.
// Information of a specific Shopping List by ID
ShoppingList shoppingListInfo = httpApiRoot
  .shoppingLists()
  .withId("{shoppingListID}")
  .get()
  .executeBlocking()
  .getBody();
// Information of a specific Shopping List by key
ShoppingList shoppingListInfo = httpApiRoot
  .shoppingLists()
  .withKey("{shoppingListKey}")
  .get()
  .executeBlocking()
  .getBody();
The shoppingListInfo object would then contain all the data of the specified Shopping List. You can access information from the fields within that object:
Screenshot of autocomplete for ShoppingList object

Get multiple resources

When returning a list of resources, use a PagedQueryResponse based on the resource you want to return. For example, a ShoppingListPagedQueryResponse returns Shopping Lists.
PagedQueryResponse is identical to PagedQueryResult in the HTTP API.
// Return all Shopping Lists in a PagedQueryResponse
ShoppingListPagedQueryResponse allShoppingLists = httpApiRoot
  .shoppingLists()
  .get()
  .executeBlocking()
  .getBody();
You can alter the results of these calls by including .withWhere(), .withSort(), .withExpand(), .withLimit(), or .withOffset() after .get().
These are identical to the parameters you can add to standard HTTP API calls. If your IDE supports autocomplete you can view a full list of methods available:
Screenshot of autocomplete for parameters

Use the Query Predicate builder

For querying results you can also use the type safe Query Predicate builders. They allow you to programmatically create a Query Predicate using the withQuery method.
// Return all Customers that have not verified their email address
final CustomerPagedQueryResponse response = httpApiRoot
  .customers()
  .get()
  .withQuery(c -> c.isEmailVerified().is(false))
  .executeBlocking()
  .getBody();

View results

You can access the list of resources within a PagedQueryResponse using .getResults():
// Return all Shopping Lists
ShoppingListPagedQueryResponse allShoppingLists = httpApiRoot
  .shoppingLists()
  .get()
  .executeBlocking()
  .getBody();

// Put the returned Shopping Lists in a new list
List<ShoppingList> listOfShoppingLists = allShoppingLists.getResults();

// Create a String containing the first Shopping List's English name
String firstShoppingListName = listOfShoppingLists.get(0).getName().get("en");

Write a resource

When writing to a resource, include the httpApiRoot and the associated endpoint.
// Create a Shopping List
ShoppingList newShoppingList = httpApiRoot
.shoppingLists()
// ...

// Update a Shopping List
ShoppingList updatedShoppingList = httpApiRoot
.shoppingLists()
// ...

Create a new resource

Creating a new resource requires a draft of the resource to create. For Shopping Lists this is a ShoppingListDraft. You create these drafts using builders:
// Create ShoppingListDraft with required fields
ShoppingListDraft newShoppingListDraft = ShoppingListDraft
  .builder()
  .name(
    LocalizedString
      .builder()
      .addValue("en", "English name of Shopping List")
      .build()
  )
  .build();
Include this draft within post() followed by .executeBlocking() and .getBody().
// Create a Shopping List
ShoppingList newShoppingList = httpApiRoot
  .shoppingLists()
  .post(newShoppingListDraft)
  .executeBlocking()
  .getBody();

Update an existing resource

Updating an existing resource requires a .withId() or .withKey() that references a unique identifier of the resource.
// Update a Shopping List
ShoppingList updatedShoppingList = httpApiRoot
  .shoppingLists()
  .withId("{shoppingListID}")
  // ...
When posting to a specific resource, you must include a payload. This payload (in the case of Shopping Lists, a ShoppingListUpdate) contains an array of update actions and the last seen version of the resource.
You can create update actions and payloads by using builders.
// Create the payload - a ShoppingListUpdate - with the current version of the Shopping List and the update actions.
ShoppingListUpdate shoppingListUpdate = ShoppingListUpdateBuilder
  .of()
  .version(1L)
  .plusActions(actionBuilder ->
    actionBuilder.setKeyBuilder().key("a-new-shoppinglist-key")
  )
  .build();
You must pass the payload as an argument to the .post() method.
// Update a Shopping List
ShoppingList updatedShoppingList = httpApiRoot
  .shoppingLists()
  .withId("{shoppingListID}")
  .post(shoppingListUpdate)
  .executeBlocking()
  .getBody();

Delete a resource

Deleting a resource requires using the .delete() method with the last seen version of the resource. You must identify the resource to delete using withId() or withKey().
// Delete and return a Shopping List
ShoppingList deletedShoppingList = httpApiRoot
  .shoppingLists()
  .withId("{shoppingListID}")
  .delete()
  .withVersion(1l)
  .withDataErasure(true) // Include to erase related personal data
  .executeBlocking()
  .getBody();

Retrieve the raw API response

The above examples use .executeBlocking() to return the resource as an instance of an object.
To return the response as a byte array instead, use .sendBlocking(). Note that with this approach you must create a byte array as the value to return:
// Return a ShoppingListPagedQueryResponse as a byte array
byte[] shoppingLists = httpApiRoot.shoppingLists().get().sendBlocking().getBody();

// Convert to a String and output to the console
String shoppingListDetails = new String(
  shoppingLists,
  java.nio.charset.StandardCharsets.UTF_8
);
System.out.println(shoppingListDetails);

Use GraphQL

With the help of the DGS codegen you can generate a type safe query and projection builder. The results are then mapped to the correct response type.

The response types have all available fields, but only the projected will contain a value.

final GraphQLRequest<ProductQueryResult> productQuery = GraphQL
  .products(query -> query.localeProjection(Collections.singletonList("en")))
  .projection(root ->
    root.results().id().key().productType().key().getParent().createdAt()
  );

final ApiHttpResponse<GraphQLResponse<ProductQueryResult>> response =
  projectRoot.graphql().query(productQuery).executeBlocking();

final ProductQueryResult data = response.getBody().getData();

Use non-blocking calls

The Java SDK also allows non-blocking calls which return a CompletableFuture.
To return the resource as an instance of an object use .execute(). To return a byte array use .send():
// Return all Shopping Lists using a CompletableFuture - execute()
apiRoot
  .shoppingLists()
  .get()
  .execute()
  .thenAccept(response -> {
    ShoppingListPagedQueryResponse allShoppingLists = response.getBody();
    // Assign the first Shopping List's ID to a string and output it to the console
    String firstshoppingListID = allShoppingLists.getResults().get(0).getId();
    System.out.println(firstshoppingListID);
  })
  .join();

// Return all Shopping Lists in a byte array using a CompletableFuture - send()
apiRoot
  .shoppingLists()
  .get()
  .send()
  .thenAccept(response -> {
    byte[] shoppingLists = response.getBody();
    // Convert to a String and output to the console
    String shoppingListDetails = new String(
      shoppingLists,
      java.nio.charset.StandardCharsets.UTF_8
    );
    System.out.println(shoppingListDetails);
  })
  .join();

Next steps

Continue learning about the Java SDK by checking our SDK code examples. You will find example code for creating, querying, and updating Customers and Products.
The Me Endpoint Checkout app demonstrates how to use the Me endpoints to create an example web store.