Delivery Java and Android SDK that supports both Rx and OkHttp client.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github
.idea
.travis
delivery-android
delivery-core
delivery-rx
delivery-tests Update README.md Oct 31, 2018
gradle/wrapper Adds copyright Oct 27, 2017
sample-android-app
sample-java-app
.gitignore
.travis.yml
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE.md
README.md
RELEASE.md
build.gradle
gradle.properties
gradlew
gradlew.bat
settings.gradle

README.md

Build Status Forums

Kentico Cloud Delivery JavaRx/AndroidRx SDK

Platform Maven Central Package jCenter Package
Android Android Android
JavaRx JavaRx JavaRx

Summary

Kentico Cloud Delivery JavaRx/AndroidRx SDK is a client library for retrieving content from Kentico Cloud. It is written in Java 7 for both Java & Android projects. The SDK is available as delivery-rx and delivery-android on Maven Central and jCenter.

The SDK is built with ReactiveX programming and supports RxJava2 and RxAndroid querying. It also integrates with OkHttp for those developers who do not want to use Rx.

Prerequisites

Java 7+

Android 2.3+ (minSdk 21)

Getting started

The first step is to include the SDK in your project, for example, as a Gradle compile dependency. Based on your project type, choose one of the following:

Java

implementation 'com.kenticocloud:delivery-rx:3.0.0'

Android

implementation 'com.kenticocloud:delivery-android:3.0.0'

Note: The only difference between these two dependencies is the 'Observable' they present for ReactiveX to subscribe to. Android will present a standard Rx2AndroidNetworking request while Java will present a generic http request as an observable. Most of your imports will come from the shared com.kenticocloud.delivery_core which is automatically included with both packages.

Configuration

// Kentico Cloud project ID
String projectId = "683771be-aa26-4887-b1b6-482f56418ffd";

// Type resolvers are required to convert the retrieved content items to their strongly-typed models
// based on their 'system.type' property
List<TypeResolver<?>> typeResolvers = new ArrayList<>();

// First, create strongly-typed models representing your items. 
// This is optional, but strongly recommended. It is best practice to use safe types 
// instead of relying on dynamic objects and values. For more details, see
// https://developer.kenticocloud.com/v1/docs/strongly-typed-models
// Here is an example of a strongly-typed model of the 'Cafe' content type.
public final class Cafe extends ContentItem {

    // Codename of your content type in Kentico Cloud
    public static final String TYPE = "cafe";

    @ElementMapping("country")
    public TextElement country;

    @ElementMapping("email")
    public TextElement email;

    public String getCountry() {
        return country.getValue();
    }

    public String getEmail() {
        return email.getValue();
    }
}

// Adds a type resolver that will eventually convert items from JSON to your strongly-typed models at runtime.
// Please note that you currently need to have models for all content types you want to work with.
// We plan to release an update that will allow you to return 
// a generic ContentItem if the strongly-typed model is not found.
typeResolvers.add(new TypeResolver<>(Cafe.TYPE, new Function<Void, Cafe>() {
    @Override
    public Cafe apply(Void input) {
        return new Cafe();
        }
    }
));

// Prepares configuration object
// Note that there are also other parameters, for example, a preview API key
DeliveryConfig config = DeliveryConfig.newConfig(projectId)
    .withTypeResolvers(typeResolvers);

Initialization

Java

Imports

import com.kenticocloud.delivery_rx.DeliveryService;
import com.kenticocloud.delivery_core.IDeliveryService;

Service

IDeliveryService deliveryService = new DeliveryService(config);

Android

Imports

import com.kenticocloud.delivery_android.DeliveryAndroidService;
import com.kenticocloud.delivery_core.IDeliveryService;

Service

IDeliveryService androidDeliveryService = new DeliveryAndroidService(config);

Get data with Rx (Observables pattern)

deliveryService.<Cafe>items()
    .type(Cafe.TYPE)
    .getObservable()
    .subscribe(new Observer<DeliveryItemListingResponse<Cafe>>() {
        @Override
        public void onSubscribe(Disposable disposable) {
        }

        @Override
        public void onNext(DeliveryItemListingResponse<Cafe> response) {
            // Gets cafe items
            List<Cafe> cafes = response.getItems();

            // Uses a method from your strongly-typed model
            String country = cafes.get(0).getCountry();
        }

        @Override
        public void onError(Throwable throwable) {
        }

        @Override
        public void onComplete() {
        }
    });

Get data using HttpAdapter (OkHttp client)

DeliveryItemListingResponse<Cafe> response = this.deliveryService.<Cafe>items()
    .type(Cafe.TYPE)
    .get();
        
List<Cafe> cafes = response.getItems();

API Reference

Property binding

  1. Make sure that your model extends the ContentItem class.
  2. Create public fields with an ElementMapping decorator. This will make sure that the value from your field is mapped to the content item element.
  3. Based on the type of field, choose the proper element type. Supported element types include: AssetsElement, ContentElement, DateTimeElement, LinkedItemsElement, MultipleChoiceElement, NumberElement, RichTextElement, TaxonomyElement, TextElement and UrlSlugElement.

The following example shows a typical class with different types of elements:

public final class Coffee extends ContentItem {

    public static final String TYPE = "coffee";

    @ElementMapping("product_name")
    public TextElement productName;

    @ElementMapping("price")
    public NumberElement price;

    @ElementMapping("image")
    public AssetsElement image;

    @ElementMapping("short_description")
    public RichTextElement shortDescription;
}

Filtering, sorting

The SDK contains all available filters and other parameters (sort, projection, paging) as predefined methods for each query type (different options are available for items and taxonomies query). All of these methods are written in a builder pattern to help you create queries more efficiently.

Example:

MultipleItemQuery<Cafe> query = deliveryService.<Cafe>items()
    .equalsFilter("elements.title", "London")
    .limitParameter(5)
    .depthParameter(2)
    .orderParameter("elements.street", OrderType.Desc);

If you need to add other query parameters to the URL directly, you can use the addParameter method:

MultipleItemQuery<Cafe> query = deliveryService.<Cafe>items()
    .addParameter(new Filters.EqualsFilter("elements.title", "London"));

Querying data

Each type of data (item, taxonomy, elements, etc.) can be obtained using the methods available in IDeliveryClient.

Basic examples of different queries:

// Gets items
SingleItemQuery<Cafe> cafeQuery = deliveryService.<Cafe>item("boston");
MultipleItemQuery<Cafe> cafesQuery = deliveryService.<Cafe>items();

// Gets types
SingleTypeQuery typeQuery = deliveryService.type("Cafe");
MultipleTypeQuery typesQuery = deliveryService.types();

// Gets taxonomies
SingleTaxonomyQuery taxonomyQuery = deliveryService.taxonomy("personas");
MultipleTaxonomyQuery taxonomiesQuery = deliveryService.taxonomies();

// Gets elements
SingleContentTypeElementQuery elementQuery = deliveryService.contenTypeElement("cafe", "country");

To execute a query, choose either get or getObservable method depending on whether you want to work with the ReactiveX API or not.

// Get examples
Cafe cafe = cafeQuery.get().getItem();
List<Cafe> cafes = cafesQuery.get().getItems();

// Observable examples
cafesQuery.getObservable()
    .subscribe(new Observer<DeliveryItemListingResponse<Cafe>>() {
        @Override
        public void onSubscribe(Disposable disposable) {
        }

        @Override
        public void onNext(DeliveryItemListingResponse<Cafe> response) {
            // Gets cafe items
            List<Cafe> cafes = response.getItems();

            // Uses a method from your strongly typed model
            String country = cafes.get(0).getCountry();
        }

        @Override
        public void onError(Throwable throwable) {
        }

        @Override
        public void onComplete() {
        }
    });

Custom query parameters

It is possible to create custom query parameters in case you need more information in the URL. This can be useful if you use a proxy and need to log additional information.

To create a custom parameter, implement IQueryParameter and use it in combination with the addParameter query method.

public static class CustomFilter implements IQueryParameter {

    private String data;

    public CustomFilter(String data){
        this.data = data;
    }

    @Override
    public String getParam() {
        return "customData";
    }

    @Override
    public String getParamValue() {
        return this.data;
    }
}

MultipleItemQuery<Cafe> query = deliveryService.<Cafe>items()
    .addParameter(new CustomFilter("result"));

Preview mode

To enable preview mode, pass your Preview API key to the configuration object.

new DeliveryConfig(projectId, typeResolvers, "yourPreviewAPIKey");

To make calls to the Preview API globally, use a default QueryConfig during initialization. You can override this when executing particular queries.

// Configures global query config that will enable preview mode by default.
QueryConfig defaultQueryConfig = new QueryConfig();
defaultQueryConfig.setUsePreviewMode(true);

DeliveryConfig config = new DeliveryConfig(projectId, typeResolvers, defaultQueryConfig);


// Enables preview mode for a specific call. This overrides global configuration.
MultipleItemQuery<Cafe> query = deliveryService.<Cafe>items()
    .type(Cafe.TYPE)
    .setUsePreviewMode(true);

Getting URL of query

You can get the URL of a query without executing it by calling the getQueryUrl method on any IQuery object.

deliveryService.items()
    .equalsFilter("elements.title", "Warrior")
    .limitParameter(5)
    .depthParameter(2)
    .skipParameter(1)
    .getQueryUrl();

The code above outputs the following URL:

https://deliver.kenticocloud.com/683771be-aa26-4887-b1b6-482f56418ffd/items?elements.title=Warrior&limit=5&depth=2&skip=1

Advanced configuration

During initialization of the DeliveryConfig you can configure the following options:

Method Use
withTypeResolvers Sets type resolvers responsible for mapping API responses to strongly-typed models.
withPreviewApiKey Sets preview API key.
withSecuredApiKey Sets secured API key.
withDeliveryApiUrl Sets custom URL of a Kentico Cloud endpoint.
withDeliveryPreviewApiUrl Sets custom URL of a Kentico Cloud preview endpoint.
withThrowExceptionForUnknownTypes If enabled, the SDK will throw an Exception when it cannot find a strongly-typed model (type resolver) of an item in the response.
withDefaultQueryConfig Sets default query config for all queries. This is useful when you want to set a default behavior and then override it on a per-query level.

Example:

IDeliveryConfig config = DeliveryConfig.newConfig("projectId")
    .withPreviewApiKey("previewApiKey")
    .withThrowExceptionForUnknownTypes(true)
    .withDeliveryApiUrl("customDeliveryEndpointUrl");

Handling errors

The SDK will automatically map Kentico Cloud error responses to a KenticoCloudResponseException runtime exception that you can handle.

try {
    DeliveryItemListingResponse<IContentItem> response = deliveryService.items().get();
} catch (KenticoCloudResponseException ex) {
    String cloudErrorMessage = ex.getMessage(); // i.e. missing item
} catch (Exception ex){
    // other error
}

Sample applications

Android JavaRx
Android JavaRx

Feedback & Contributing

Check out the contributing page to see the best places to file issues, start discussions, and begin contributing.

Analytics