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.
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 Java SDK
Gradle
Add the following to your build.gradle file.
This has been configured to install 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}"implementation "com.commercetools.sdk:commercetools-sdk-java-importapi:${versions.commercetools}"implementation "com.commercetools.sdk:commercetools-sdk-java-history:${versions.commercetools}"}
Maven
Add the following to your pom.xml file.
This has been configured to install 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></dependency><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></dependencies>
Maven Central
You can find a full list of commercetools SDKs and the latest versions at Maven Central Repository Search.
For any of the SDK modules an HTTP client module must be installed. The default one is commercetools-http-client
.
The commercetools-sdk-java-importapi
(Import API) and commercetools-sdk-java-history
(Change History API) are only needed for more specific use cases.
Troubleshooting 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:
// Add your package information here// Required importsimport com.commercetools.api.client.ProjectApiRoot;import com.commercetools.api.defaultconfig.ApiRootBuilder;import com.commercetools.api.defaultconfig.ServiceRegion;import io.vrap.rmf.base.client.oauth2.*;public class Client {public static ProjectApiRoot createApiClient() {final ProjectApiRoot apiRoot = ApiRootBuilder.of().defaultClient(ClientCredentials.of().withClientId("{clientID}").withClientSecret("{clientSecret}").build(),ServiceRegion.YOUR_SERVICE_REGION).build("{projectKey}");return apiRoot;}}
ServiceRegion
is an enum and you should use one of the following values based on where your commercetools Project is hosted:
ServiceRegion value | Region |
---|---|
ServiceRegion.GCP_EUROPE_WEST1 | europe-west1.gcp |
ServiceRegion.GCP_US_CENTRAL1 | us-central1.gcp |
ServiceRegion.AWS_US_EAST_2 | us-east-2.aws |
ServiceRegion.AWS_EU_CENTRAL_1 | eu-central-1.aws |
ServiceRegion.GCP_AUSTRALIA_SOUTHEAST1 | australia-southeast1.gcp |
ServiceRegion.AZURE_EASTUS | eastus.azure |
ServiceRegion.AZURE_GERMANYWESTCENTRAL | germanywestcentral.azure |
Test the Client
In your Java program, add the following code:
// Required importsimport com.commercetools.api.client.ProjectApiRoot;import com.commercetools.api.models.project.*;// Create the apiRoot with your ClientProjectApiRoot apiRoot = Client.createApiClient();// Make a get call to the ProjectProject myProject = apiRoot.get().executeBlocking().getBody();// Output the Project nameSystem.out.println(myProject.getName());
You can now use apiRoot
to build requests to the Composable Commerce API.
This code includes an example API call that gets your Project to the myProject
object and outputs the Project's name using .getName()
.
Using 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.*;
You can find a list of the available packages to import in the Javadoc.
Using builders
The Java SDK follows a builder pattern when constructing drafts, update actions, and other objects/types that contain multiple fields.
// Create a LocalizedStringLocalizedString multiLanguageString = LocalizedString.builder().addValue("en", "English value").addValue("de", "German value").build();// Create US$100.00Money money = Money.builder().currencyCode("USD").centAmount(10000l).build();// Create a CategoryCategoryDraft categoryDraft = CategoryDraft.builder().name(LocalizedString.ofEnglish("english name")).slug(stringBuilder -> stringBuilder.addValue("en", "english-slug")).key("category-key").build();
Consult the HTTP API reference to ensure that all required fields are included.
Once the fields/values are added, .build()
finishes building the object.
Structure your API call
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 ListShoppingList shoppingListInfo// ...// Return all Shopping ListsShoppingListPagedQueryResponse allShoppingLists// ...// Create an update action for setting a Shopping List keyShoppingListSetKeyAction shoppingListSetKeyAction// ...
Retrieving data
When retrieving, include the apiRoot
and the associated endpoint.
// Get information of a specific Shopping ListShoppingList shoppingListInfo = apiRoot.shoppingLists()// ...// Return all Shopping ListsShoppingListPagedQueryResponse allShoppingLists = apiRoot.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 IDShoppingList shoppingListInfo = apiRoot.shoppingLists().withId("{shoppingListID}").get().executeBlocking().getBody();
// Information of a specific Shopping List by keyShoppingList shoppingListInfo = apiRoot.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:
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 PagedQueryResponseShoppingListPagedQueryResponse allShoppingLists = apiRoot.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:
Using 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 addressfinal CustomerPagedQueryResponse response = apiRoot.customers().get().withQuery(c -> c.isEmailVerified().is(false)).executeBlocking().getBody();
Viewing results
You can access the list of resources within a PagedQueryResponse
using .getResults()
:
// Return all Shopping ListsShoppingListPagedQueryResponse allShoppingLists = apiRoot.shoppingLists().get().executeBlocking().getBody();// Put the returned Shopping Lists in a new listList<ShoppingList> listOfShoppingLists = allShoppingLists.getResults();// Create a String containing the first Shopping List's English nameString firstShoppingListName = listOfShoppingLists.get(0).getName().get("en");
Writing a resource
When writing to a resource, include the apiRoot
and the associated endpoint.
// Create a Shopping ListShoppingList newShoppingList = apiRoot.shoppingLists()// ...// Update a Shopping ListShoppingList updatedShoppingList = apiRoot.shoppingLists()// ...
Creating 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 fieldsShoppingListDraft 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 ListShoppingList newShoppingList = apiRoot.shoppingLists().post(newShoppingListDraft).executeBlocking().getBody();
Updating an existing resource
Updating an existing resource requires a .withId()
or .withKey()
that references a unique identifier of the resource.
// Update a Shopping ListShoppingList updatedShoppingList = apiRoot.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.
Update actions and payloads are created 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-unique-shoppinglist-key")).build();
You must pass the payload as an argument to the .post()
method.
// Update a Shopping ListShoppingList updatedShoppingList = apiRoot.shoppingLists().withId("{shoppingListID}").post(shoppingListUpdate).executeBlocking().getBody();
Deleting 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 ListShoppingList deletedShoppingList = apiRoot.shoppingLists().withId("{shoppingListID}").delete().withVersion(1l).withDataErasure(true) // Include to erase related personal data.executeBlocking().getBody();
Retrieving 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 arraybyte[] shoppingLists = apiRoot.shoppingLists().get().sendBlocking().getBody();// Convert to a String and output to the consoleString shoppingListDetails = new String(shoppingLists,java.nio.charset.StandardCharsets.UTF_8);System.out.println(shoppingListDetails);
Using GraphQL
The Java SDK has a GraphQL module that provides type safe GraphQL support.
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();
Using 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 consoleString 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 consoleString shoppingListDetails = new String(shoppingLists,java.nio.charset.StandardCharsets.UTF_8);System.out.println(shoppingListDetails);}).join();
Next steps
Try our example code
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.
Set up a demo application
The Me Endpoint Checkout app demonstrates how to use the Me endpoints to create an example web store.