This is the early access documentation preview for Custom Views. This documentation might not be in sync with our official documentation.
Java SDK Overview
Integrate applications running on the Java Virtual Machine (JVM) with Composable Commerce.
About the Java SDK
The Java SDK (also referred to as the Java v2 SDK) enables you to use Java 8 methods and objects to interact with Composable Commerce APIs rather than using plain HTTP calls and untyped JSON node objects.
Users gain type-safety, encapsulation, IDE autocompletion, and an internal domain-specific language to discover and formulate valid requests.
It supports multiple languages that run on the JVM, including:
- Java
- Scala
- Groovy
- Clojure
- Kotlin
Get started
Learn how to set up and use the Java SDK with our get started guide.
Refer to our integration tests for examples of creating, querying, updating, and deleting resources in your Composable Commerce Project.
Migrate from the v1 SDK
Learn how to migrate to the Java v2 SDK by following our migration guide.
Javadoc
The full Javadoc reference can be found here.
SDK features
The Java SDK uses various Java 8 language constructs and classes, including:
As a result of Java 8 dependencies, the Java SDK is unsuitable for Android development as it does not (yet) support Java 8 on its virtual machine.
Good defaults for equals() and hashCode()
The SDK's model implementation classes provide default implementations for these methods using reflection.
Client interfaces
The HTTP client abstract itself is a functional interface and can be replaced with test doubles.
Model factory methods
Each model has a factory method ::of()
to create a new empty instance. The method ::builder()
returns a new builder instance.
Helper Methods
Use helper methods to perform repetitive tasks in the Java SDK. You can find a complete list of helper methods including example usage in the Javadoc.
Get the source on GitHub
The Java SDK is fully open source and is available on GitHub.
License
The Java SDK is provided under the Apache License.
Release notes
The release notes for the Java SDK can be found on GitHub.
Best practices and error handling
A complete list of best practices can be found on GitHub
You can find integration tests for each endpoint here. These tests also provide code examples for creating, querying, updating, and deleting resources within your Composable Commerce Project.
Exceptions
The Java SDK uses exceptions from the Java Development Kit (such as IllegalArgumentException) and provides its own exceptions which inherit from BaseException.
Problems concerning the ApiHttpClient throw an ApiHttpException.
JSON serializing and deserializing problems throw JsonException.
ApiHttpException is a base exception for all error responses (HTTP status code >= 400).
ApiClientException expresses errors which can be recovered by the client side (HTTP status code >= 400 and < 500). ApiServerException is for server errors.
Errors
If a command cannot be performed due to unfulfilled preconditions, one error response with multiple errors can be returned (for more information, see HTTP API Errors). The Java SDK then adds a BadRequestException into a CompletionStage.
Custom HttpExceptionFactory
Responses with a status code of 400 (or higher) are treated as errors and raise exceptions. These exceptions are created by the DefaultHttpExceptionFactory. In case you want to override the handling you have to implement this interface and override the default methods if necessary.
public class HttpExceptionFactoryTest {static class CustomExceptionFactory implements HttpExceptionFactory {@Overridepublic ApiHttpException create(ApiHttpRequest request,ApiHttpResponse<byte[]> response) {return new ApiHttpException(response.getStatusCode(),request.getSecuredBody(),response.getHeaders(),"something bad happened",response,request);}@Overridepublic ResponseSerializer getResponseSerializer() {return ResponseSerializer.of();}}@Testpublic void customFactory() {ProjectApiRoot client = ApiRootBuilder.of().defaultClient(ServiceRegion.GCP_EUROPE_WEST1.getApiUrl()).withHttpExceptionFactory(CustomExceptionFactory::new).build("my-project-key");assertThatExceptionOfType(ApiHttpException.class).isThrownBy(() -> client.get().executeBlocking()).withMessageStartingWith("detailMessage: something bad happened");}}
Logging
Internal logging used by the commercetools client itself uses a SLF4J logger named commercetools
.
Log information
The default logger middleware logs the following information per level.
Error
When an ApiHttpException occurs, the HTTP method, URI, and response status code are logged. For any other exception, the cause and exception are logged.
Information
By default any response by the API is logged with the HTTP method, URI, and response status code. If a deprecated header was submitted in the response, an information entry with the deprecation notice is logged.
The log level for these events can be configured when instantiating the InternalLoggerMiddleware.
Debug
The request and the response object are logged as a string representation including headers and body. Sensitive data like auth tokens and passwords are redacted.
Trace
The request and response are logged with a pretty-printed output. Sensitive data like auth tokens and passwords are redacted.
Logger hierarchy
The loggers form a hierarchy separated by a period. The root logger is commercetools
.
The child loggers of commercetools are the endpoints. For example commercetools.categories
for Categories and commercetools.product-types
for Product Types.
The grandchild loggers refer to the action. commercetools.categories.request
refers to performing requests per HTTPS to commercetools for Categories, commercetools.categories.response
refers to the responses.
The logger makes use of different log levels, so for example commercetools.categories.response
logs the HTTP response on debug level:
[OkHttp https://api.europe-west1.gcp.commercetools.com/...] DEBUG commercetools.categories.response - io.vrap.rmf.base.client.ApiHttpResponse@33e37acd[statusCode=200,headers=...,textInterpretedBody={"limit":20,"offset":0,"count":4,"total":4,"results":[{"id":"ca7f64dc-ab41-4e7f-b65b-bfc25bf01111","version":1,"createdAt":"2021-01-06T09:21:55.445Z","lastModifiedAt":"2021-01-06T09:21:55.445Z","key":"random-key-15aab6ee-9a48-4fdc-a8c3-8ff9ff390d60","name":{"key-6bc3cc62-1995-43f4":"value-random-string-c3ff7f1a-6371-4c0c-a3b9-5060eca08b8a"},"slug":{"key-6bc3cc62-1995-43f4":"value-random-string-c3ff7f1a-6371-4c0c-a3b9-5060eca08b8a"},"description":{"key-6bc3cc62-1995-43f4":"value-random-string-c3ff7f1a-6371-4c0c-a3b9-5060eca08b8a"},"ancestors":[],"orderHint":"random-string-a99e6941-3225-4766-923a-4a654652532f","externalId":"random-id-100b3851-29b4-47c1-aef3-860b4cd28f54"}]}]
Additionally, commercetools.categories.response
logs the formatted HTTP response on trace level:
[OkHttp https://api.europe-west1.gcp.commercetools.com/...] TRACE commercetools.categories.response - 200{"limit" : 20,"offset" : 0,"count" : 4,"total" : 4,"results" : [ {"id" : "bcb15128-b69e-47b6-81c4-1ea5f9a63b83","version" : 1,"createdAt" : "2021-01-06T09:21:50.485Z","lastModifiedAt" : "2021-01-06T09:21:50.485Z","createdBy" : {"clientId" : "h-QvaF3NpsjPBWeXa6TUOnq0","isPlatformClient" : false},"key" : "random-key-f45535f5-1111-4bfb-98ac-164234ac2c73","name" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"},"slug" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"},"description" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"},"ancestors" : [ ],"orderHint" : "random-string-6b88f299-d4ca-491a-9d7c-3463e718c8d2","externalId" : "random-id-b98a5ab4-5413-40b3-8119-eb5ac2b5afbb","metaTitle" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"},"metaKeywords" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"},"metaDescription" : {"key-b7d87008-9526-47b3-8b80" : "value-random-string-baf1a1ae-3726-4573-bec5-2c53c7d1114a"}}, {...} ]}
commercetools.products.responses.queries
only logs HTTP GET requests and commercetools.products.responses.commands
only logs HTTP POST/DELETE requests.
[pool-1-thread-1] DEBUG commercetools.products.request.commands - io.vrap.rmf.base.client.ApiHttpRequest@1d2c6948[method=POST,uri="https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/products",headers=[...],textInterpretedBody={"productType":{"id":"cda39953-23af-4e85-abb0-5b89517ec5f2","typeId":"product-type"},"name":{"random-string-b66de021-d2fa-4262-8837-94a6992a8cdc":"random-string-da28a010-e66b-49d4-a18b-f1bfc145d2f6"},...}][pool-1-thread-1] DEBUG commercetools.products.request.queries - io.vrap.rmf.base.client.ApiHttpRequest@53667fdb[method=GET,uri="https://api.europe-west1.gcp.commercetools.com/test-php-dev-integration-1/products/ef745227-b115-4132-ba2c-4e46db80df79",headers=[...],textInterpretedBody=empty body]