Class Migration

java.lang.Object
com.commercetools.docs.meta.Migration

public class Migration extends Object
Table of content

SDK v1 compatibility module

The SDK provides a compatibility module. This module e.g. allows the usage of the SDKv2 client with in conjunction with all the commands of the SDKv1. For more details please see Compatibility

Client Configuration and Creation

From the 1.x we substitute the SphereClientFactory class with the ApiRootBuilder class in the 2.x.

The benefit is that after the ApiRootBuilder has been defined, it's easy to create the requests directly from it. There are example below that can clarify the behaviour.

v1

final SphereClient sphereClient = SphereClientFactory.of()
        .createClient("projectKey", "clientId", "clientSecret");

See the test code.

v2
final ProjectApiRoot projectRoot = ApiRootBuilder.of()
        .defaultClient(ClientCredentials.of().withClientId("clientId").withClientSecret("clientSecret").build(),
            ServiceRegion.GCP_EUROPE_WEST1.getOAuthTokenUrl(), ServiceRegion.GCP_EUROPE_WEST1.getApiUrl())
        .build("projectKey");

See the test code.

Timeout Setting

In both versions is the executeBlocking() method that sets the timeout.

v1

PagedQueryResult<Category> response = blockingClient.executeBlocking(CategoryQuery.of(), 45, TimeUnit.SECONDS);

See the test code.

v2
CategoryPagedQueryResponse response = projectApiRoot.categories()
        .get()
        .executeBlocking(Duration.ofSeconds(45))
        .getBody();

See the test code.

Headers

To set headers, in the 1.x there is the HttpRequest class and in the 2.x the ApiHttpRequest class.

The main difference, as you can see the example below, is that the ApiHttpRequest can be directly instantiated and it can be directly set the type of method (GET or POST), the URI, the headers and the body.

v1

There is no way to set the header directly in the request
v2
final CartPagedQueryResponse carts = projectApiRoot.carts()
        .get()
        .addHeader("foo", "bar")
        .executeBlocking()
        .getBody();

See the test code.

Retry

In the examples below there is a huge difference about the *Retry* for the v1 and v2.

As can be seen, in the v1, it has to be define piece by piece: the retry rules, then the SphereClient and then the request in this case PagedQueryResult.

On the contrary in the v2, the setup of the request can be built directly during the client creation, so we are going to have the ByProjectKeyRequestBuilder built including the setting of the Retry through the RetryMiddleware and as a plus, like in this case, it is possible to set up other parameters to our request like the logger InternalLoggerFactory. After that, we will have our request CategoryPagedQueryResponse.

v1

final int maxAttempts = 5;
final List<RetryRule> retryRules = Collections.singletonList(RetryRule.of(
    RetryPredicate.ofMatchingStatusCodes(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504),
    RetryAction.ofExponentialBackoff(maxAttempts, 100, 2000)));
final SphereClient client = RetrySphereClientDecorator.of(sphereClient, retryRules);

final PagedQueryResult<Category> categoryPagedQueryResult = client.execute(CategoryQuery.of())
        .toCompletableFuture()
        .get();

See the test code.

v2
final ProjectApiRoot projectClient = ApiRootBuilder.of()
        .defaultClient(ServiceRegion.GCP_EUROPE_WEST1.getApiUrl(),
            ClientCredentials.of().withClientId("clientId").withClientSecret("clientSecret").build(),
            ServiceRegion.GCP_EUROPE_WEST1.getOAuthTokenUrl())
        .withPolicies(policies -> policies.withRetry(builder -> builder
                .statusCodes(Arrays.asList(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504))))
        .build("projectKey");

final CategoryPagedQueryResponse body = projectClient.categories().get().executeBlocking().getBody();

See the test code.

Draft Builder

About the *DraftBuilder* the main difference is that in the 2.x there are not inheritances for the *DraftBuilder* classes, but there are no so much differences in the behaviour.

v1

LocalizedString name = LocalizedString.ofEnglish("name");
LocalizedString slug = LocalizedString.ofEnglish("slug");
LocalizedString metaDescription = LocalizedString.ofEnglish("metaDescription");
LocalizedString metaTitle = LocalizedString.ofEnglish("metaTitle");
LocalizedString metaKeywords = LocalizedString.ofEnglish("metaKeywords");
CategoryDraft categoryDraft = CategoryDraftBuilder.of(name, slug)
        .metaDescription(metaDescription)
        .metaTitle(metaTitle)
        .metaKeywords(metaKeywords)
        .externalId("externalId")
        .build();

See the test code.

v2
LocalizedString name = LocalizedString.ofEnglish("name");
LocalizedString slug = LocalizedString.ofEnglish("slug");
LocalizedString metaDescription = LocalizedString.ofEnglish("metaDescription");
LocalizedString metaTitle = LocalizedString.ofEnglish("metaTitle");
LocalizedString metaKeywords = LocalizedString.ofEnglish("metaKeywords");

CategoryDraft categoryDraft = CategoryDraftBuilder.of()
        .name(name)
        .slug(slug)
        .externalId("externalId")
        .metaTitle(metaTitle)
        .metaDescription(metaDescription)
        .metaKeywords(metaKeywords)
        .build();

See the test code.

Create Command

In the v2 there are not dedicated classes for the Create Command, but there are builders (you can see better in the Update Command. It means that to have a request it needs to have a draft to build which has to be passed into the post() method.

v1

LocalizedString name = LocalizedString.ofEnglish("name");
LocalizedString slug = LocalizedString.ofEnglish("slug");
CategoryDraft categoryDraft = CategoryDraftBuilder.of(name, slug).build();
Category category = blockingClient.executeBlocking(CategoryCreateCommand.of(categoryDraft));

See the test code.

v2
LocalizedString name = LocalizedString.ofEnglish("name");
LocalizedString slug = LocalizedString.ofEnglish("slug");
CategoryDraft categoryDraft = CategoryDraftBuilder.of().name(name).slug(slug).build();
Category category = projectApiRoot.categories().post(categoryDraft).executeBlocking().getBody();

See the test code.

Create From Json

The main difference in this case is that we replaced the SphereJsonUtils class with the JsonUtils class.

v1

final CategoryDraft categoryDraft = SphereJsonUtils.readObjectFromResource("category.json",
    CategoryDraft.class);
final Category category = blockingClient.executeBlocking(CategoryCreateCommand.of(categoryDraft));

See the test code.

v2
final CategoryDraft categoryDraft = JsonUtils.fromJsonString(TestUtils.stringFromResource("category.json"),
    CategoryDraft.class);
final Category category = projectApiRoot.categories().post(categoryDraft).executeBlocking().getBody();

See the test code.

Update Command

Like the Create Command, there are not dedicated classes for the *Update Command*, but the use of the UpdateBuilder to create the type of update action to apply in the post method is substantial to build the update action.

Here the differences:

v1

LocalizedString newName = LocalizedString.ofEnglish("new name");
CategoryUpdateCommand command = CategoryUpdateCommand.of(category,
    Collections.singletonList(ChangeName.of(newName)));
Category updatedCategory = blockingClient.executeBlocking(command);

See the test code.

v2
LocalizedString newName = LocalizedString.ofEnglish("new name");
CategoryUpdate categoryUpdate = CategoryUpdateBuilder.of()
        .version(category.getVersion())
        .actions(CategoryChangeNameActionBuilder.of().name(newName).build())
        .build();

Category updatedCategory = projectApiRoot.categories()
        .withId(category.getId())
        .post(categoryUpdate)
        .executeBlocking()
        .getBody();

See the test code.

Query - GetById

In case of query by Id, the v2 is not so different from the previous cases, except that it uses the get method before other ways to filter our request.

v1

Category loadedCategory = blockingClient
        .executeBlocking(CategoryByIdGet.of(category.getId()).withExpansionPaths(m -> m.parent()));

See the test code.

v2
Category queriedCategory = projectApiRoot.categories()
        .withId(category.getId())
        .get()
        .withExpand("parent")
        .executeBlocking()
        .getBody();

See the test code.

Query

To continue the previous case, to build complex query we use ResourcePagedQueryResponse (in the v1 is PagedQueryResult) which is meant to apply limit, count, total, offset, and result to our query. And the structure as the example before is to use get before other ways to filter our request.

v1

PagedQueryResult<Category> pagedQueryResult = blockingClient.executeBlocking(CategoryQuery.of().byId("id123"));

See the test code.

v2
CategoryPagedQueryResponse response = projectApiRoot.categories()
        .get()
        .withWhere("id = :id", "id", "id123")
        .executeBlocking()
        .getBody();

See the test code.

  • Constructor Details

    • Migration

      public Migration()