NextGen APIs

SDK API Reference for Private API Calls

This page documents the low-level SDK APIs available for customization developers who need to create custom PvtService or DataManager implementations and want to use our internal APIs



Overview

When creating customizations, use the following SDK components based on your customization type:

Customization Type

Component

Purpose

Custom PvtService

PrivateApiHttpClient

Execute HTTP calls to Private API endpoints

Custom DataManager

ResponseChecker

Validate responses and handle errors

Custom DataManager

ResourceExtractor

Extract data from responses with validation


PrivateApiHttpClient

Use this when: Creating a custom PvtService implementation to call Private API endpoints.

The PrivateApiHttpClient interface provides methods to execute HTTP requests to Private API endpoints. Inject it into your custom PvtService implementation.

Injection

Java
@Service
@RequiredArgsConstructor
public class CustomPvtServiceImpl implements CustomPvtService {
    private final PrivateApiHttpClient privateApiHttpClient;
    // ...
}

GET Methods

getReactive (List Response)

Retrieves a list of entities from a Private API endpoint.

Signature:

Java
<T> Mono<GetResponse<T>> getReactive(
    String uri,
    Object[] uriVariables,
    Class<T> contentClass,
    GetParams getParams,
    GetFilters getFilters
);

Parameters:

  • uri - The Private API endpoint path with placeholders (e.g., /assets/r1/assets/{assetId})

  • uriVariables - Array of values to substitute in the URI placeholders

  • contentClass - The class type of the response content

  • getParams - Query parameters (fields, pagination)

  • getFilters - Filter criteria for the query

Example:

Java
private static final String MATERIALS_API = "/inventory/materials/r1/materials";

@Override
public Mono<GetResponse<Material>> find(final GetParams getParams,
                                        final GetFilters getFilters) {
    return privateApiHttpClient.getReactive(
        MATERIALS_API,
        new Object[] {},
        Material.class,
        getParams,
        getFilters);
}

// Usage with filters
@Override
public Mono<GetResponse<Material>> findByCode(final GetParams getParams,
                                              final String code) {
    return find(getParams, singleFilter("code", code));
}

getReactive (Single Response)

Retrieves a single entity by ID from a Private API endpoint.

Signature:

Java
<T> Mono<GetSingleResponse<T>> getReactive(
    String uri,
    Object[] uriVariables,
    Class<T> contentClass,
    GetSingleParams getSingleParams
);

Example:

Java
private static final String ASSETS_BY_ASSET_ID = "/assets/r1/assets/{assetId}";

@Override
public Mono<GetSingleResponse<Asset>> findById(final GetSingleParams getSingleParams,
                                               final Long id) {
    return privateApiHttpClient.getReactive(
        ASSETS_BY_ASSET_ID,
        new Object[] {id},
        Asset.class,
        getSingleParams);
}

getSingleResponseReactive

Retrieves a single entity using list-style parameters but expecting only one result.

Signature:

Java
<T> Mono<GetSingleResponse<T>> getSingleResponseReactive(
    String uri,
    Object[] uriVariables,
    Class<T> contentClass,
    GetParams getParams,
    GetFilters getFilters
);

getReactive (Properties Response)

Retrieves property-based responses.

Signature:

Java
Mono<GetPropertiesResponse> getReactive(
    String uri,
    Object[] uriVariables,
    GetFilters getFilters
);

POST Methods

postReactive

Creates a new entity via POST request.

Signature:

Java
<R, T> Mono<PostResponse<R>> postReactive(
    String uri,
    Object[] uriVariables,
    Class<R> responseClass,
    Class<T> contentClass,
    T content
);

Parameters:

  • uri - The Private API endpoint path

  • uriVariables - Array of values to substitute in the URI placeholders

  • responseClass - The class type of the response (typically IdResponse.class or Void.class)

  • contentClass - The class type of the request body

  • content - The request body object

Example:

Java
@Override
public Mono<PostResponse<IdResponse>> createAsset(final Asset asset) {
    return privateApiHttpClient.postReactive(
        "/assets/r1/assets",
        new Object[] {},
        IdResponse.class,
        Asset.class,
        asset);
}

// POST without response body
@Override
public Mono<PostResponse<Void>> activateWorkOrder(final Long workOrderId) {
    return privateApiHttpClient.postReactive(
        "/work-orders/r1/work-orders/{workOrderId}/activations",
        new Object[] {workOrderId},
        Void.class,
        Void.class,
        null);
}

postInBatchReactive

Creates multiple entities in a batch operation.

Signature:

Java
<R, T> Mono<Collection<PostResponse<R>>> postInBatchReactive(
    String uri,
    Object[] uriVariables,
    Class<R> responseClass,
    Class<T> contentClass,
    T content
);

Example:

Java
@Override
public Mono<Collection<PostResponse<IdResponse>>> batchCreate(
        final Collection<WorkShiftException> workShiftExceptions) {
    return privateApiHttpClient.postInBatchReactive(
        "/workforce/calendars/r1/work-shift-exceptions/batch",
        new Object[] {},
        IdResponse.class,
        Collection.class,
        workShiftExceptions);
}

PUT Methods

putReactive

Updates an entity completely via PUT request.

Signature:

Java
<T> Mono<PutResponse> putReactive(
    String uri,
    Object[] uriVariables,
    Class<T> contentClass,
    T content
);

Example:

Java
@Override
public Mono<PutResponse> associateMetersWithWorkOrder(final Long workOrderId,
                                                      final WorkOrderMeters workOrderMeters) {
    return privateApiHttpClient.putReactive(
        "/work-orders/r1/work-orders/{workOrderId}/meters",
        new Object[] {workOrderId},
        WorkOrderMeters.class,
        workOrderMeters);
}

PATCH Methods

patchReactive

Partially updates an entity via PATCH request.

Signature:

Java
<T> Mono<PatchResponse> patchReactive(
    String uri,
    Object[] uriVariables,
    Class<T> contentClass,
    T content
);

Example:

Java
@Override
public Mono<PatchResponse> patchAsset(final Long assetId,
                                      final AssetPatch assetPatch) {
    return privateApiHttpClient.patchReactive(
        "/assets/r1/assets/{assetId}",
        new Object[] {assetId},
        AssetPatch.class,
        assetPatch);
}

// Batch patch
@Override
public Mono<PatchResponse> batchUpdate(final Collection<WorkShiftExceptionUpdate> workShiftExceptions) {
    return privateApiHttpClient.patchReactive(
        "/workforce/calendars/r1/work-shift-exceptions/batch",
        new Object[] {},
        Collection.class,
        workShiftExceptions);
}

DELETE Methods

deleteReactive

Deletes an entity via DELETE request.

Signature:

Java
Mono<DeleteResponse> deleteReactive(
    String uri,
    Object[] uriVariables
);

Example:

Java
@Override
public Mono<DeleteResponse> removeAssetFromParent(final Long parentAssetId,
                                                  final Long childAssetId) {
    return privateApiHttpClient.deleteReactive(
        "/assets/r1/assets/{assetId}/children/{assetChildId}",
        new Object[] {parentAssetId, childAssetId});
}

deleteReactive (with Filters)

Deletes entities matching filter criteria.

Signature:

Java
Mono<DeleteResponse> deleteReactive(
    String uri,
    Object[] uriVariables,
    DeleteFilters deleteFilters
);

Example:

Java
@Override
public Mono<DeleteResponse> batchDelete(final DeleteFilters deleteFilters) {
    return privateApiHttpClient.deleteReactive(
        "/workforce/calendars/r1/work-shift-exceptions/batch",
        new Object[] {},
        deleteFilters);
}

ResponseChecker

Use this when: Creating a custom DataManager implementation to validate Private API responses.

The ResponseChecker interface validates Private API responses and throws appropriate exceptions when errors occur. Use it in your DataManager implementations.

Injection

Java
@Component
@RequiredArgsConstructor
public class CustomDataManagerImpl implements CustomDataManager {
    private final CustomPvtService customPvtService;
    private final ResponseChecker responseChecker;
    // ...
}

throwIfResponseHasErrorReactive

Checks if the response contains an error and throws an APIException if so.

Signature:

Java
Mono<Void> throwIfResponseHasErrorReactive(HttpResponse<?> resp);

Example:

Java
@Override
public Mono<Void> updateReactive(final Long assetId,
                                 final AssetPatch assetPatch) {
    return pvtAssetService.patchAsset(assetId, assetPatch)
        .flatMap(responseChecker::throwIfResponseHasErrorReactive);
}

returnResponseCodeIfResponseHasNoErrorReactive

Returns the HTTP status code if no error, otherwise throws an exception.

Signature:

Java
Mono<HttpStatus> returnResponseCodeIfResponseHasNoErrorReactive(HttpResponse<?> resp);

ResourceExtractor

Use this when: Creating a custom DataManager implementation to extract data from Private API responses.

The ResourceExtractor interface extracts data from Private API responses with built-in validation. Use it in your DataManager implementations to safely extract entities.

Injection

Java
@Component
@RequiredArgsConstructor
public class CustomDataManagerImpl implements CustomDataManager {
    private final CustomPvtService customPvtService;
    private final ResourceExtractor resourceExtractor;
    private final ResponseChecker responseChecker;
    // ...
}

extractFirstIfExists

Extracts the first element from a list response if it exists.

Signature:

Java
<T> Optional<T> extractFirstIfExists(GetResponse<T> getResponse);

Example:

Java
@Override
public Mono<Optional<Long>> findFirstIdByCodeReactive(final String code) {
    final Mono<GetResponse<Asset>> resp =
        pvtAssetService.findByCode(GetParams.build(LIMIT_TO_ONE, singleField("id")), code);
    return resp.flatMap(assetGetResponse -> {
        final Optional<Asset> mayBeAsset =
            resourceExtractor.extractFirstIfExists(assetGetResponse);
        return Mono.just(mayBeAsset.map(Asset::getId));
    });
}

extractIfExists

Extracts the content from a single response if it exists, ignoring NOT_FOUND errors.

Signature:

Java
<T> Optional<T> extractIfExists(GetSingleResponse<T> getSingleResponse);

Example:

Java
@Override
public Mono<Optional<String>> findUniqueCodeIfExistsByIdReactive(final Long id) {
    final Mono<GetSingleResponse<Asset>> resp = pvtAssetService.findById(
        GetSingleParams.build(singleField("code")), id);
    return resp.flatMap(assetGetSingleResponse -> {
        final Optional<Asset> mayBeAsset =
            resourceExtractor.extractIfExists(assetGetSingleResponse);
        return Mono.just(mayBeAsset.map(Asset::getCode));
    });
}

extractEnsuringItIsUnique

Extracts a single entity from a list response, throwing exceptions if not found or if multiple entities exist.

Signature:

Java
<T> T extractEnsuringItIsUnique(
    GetResponse<T> getResponse,
    APIError notFoundApiError,
    List<? extends Serializable> notFoundErrorParams,
    APIError tooManyEntitiesApiError,
    List<? extends Serializable> tooManyEntitiesErrorParams
);

Example:

Java
@Override
public Mono<Asset> findUniqueFieldsByCodeAndExternalSystemIdReactive(final Set<String> fields,
                                                                     final String code,
                                                                     final Long externalSystemId) {
    final Mono<GetResponse<Asset>> resp = pvtAssetService.findByCodeAndExternalSystemId(
        GetParams.build(LIMIT_TO_TWO, multipleFields(fields)), code, externalSystemId);
    return resp.flatMap(assetGetResponse -> {
        final Asset asset = resourceExtractor.extractEnsuringItIsUnique(
            assetGetResponse,
            ASSET_NOT_EXISTS,
            singletonList(code),
            ASSET_NOT_UNIQUE,
            singletonList(code));
        return Mono.just(asset);
    });
}

extractIfExistsEnsuringItIsUnique

Extracts an optional entity, throwing an exception only if multiple entities exist.

Signature:

Java
<T> Optional<T> extractIfExistsEnsuringItIsUnique(
    GetResponse<T> getResponse,
    APIError tooManyEntitiesApiError,
    List<? extends Serializable> tooManyEntitiesErrorParams
);

Example:

Java
@Override
public Mono<Optional<Asset>> findUniqueIfExistsByCodeReactive(final String code) {
    final Mono<GetResponse<Asset>> resp =
        pvtAssetService.findByCode(GetParams.build(LIMIT_TO_TWO), code);
    return resp.flatMap(assetGetResponse -> {
        final Optional<Asset> assetOpt = resourceExtractor.extractIfExistsEnsuringItIsUnique(
            assetGetResponse,
            ASSET_NOT_UNIQUE,
            singletonList(code));
        return Mono.just(assetOpt);
    });
}

extractAll

Extracts all entities from a list response.

Signature:

Java
<T> Collection<T> extractAll(GetResponse<T> getResponse);

Example:

Java
@Override
public Mono<Collection<Material>> findAllReactive(final GetParams getParams,
                                                  final GetFilters getFilters) {
    return pvtMaterialsService.find(getParams, getFilters)
        .map(resourceExtractor::extractAll);
}

extractPage

Extracts a paginated response with content and page metadata.

Signature:

Java
<T> ResponsePage<T> extractPage(GetResponse<T> getResponse);

extractAllEnsuringEachElementIsUnique

Extracts all entities, ensuring each key maps to exactly one entity.

Signature:

Java
<T, F extends Serializable> Collection<T> extractAllEnsuringEachElementIsUnique(
    GetResponse<T> getResponse,
    Set<F> keys,
    Function<T, F> getFieldFunction,
    APIError notFoundApiError,
    APIError tooManyEntitiesApiError
);

Example:

Java
@Override
public Mono<Collection<Asset>> findAllUniqueFieldsByIdReactive(final Set<String> fields,
                                                               final Set<Long> id) {
    final Mono<GetResponse<Asset>> resp = pvtAssetService.findById(
        GetParams.build(NO_LIMITS, multipleFields(fields)), id);
    return resp.flatMap(assetGetResponse -> {
        final Collection<Asset> assets =
            resourceExtractor.extractAllEnsuringEachElementIsUnique(
                assetGetResponse,
                id,
                Asset::getId,
                ASSET_NOT_EXISTS,
                ASSET_NOT_UNIQUE);
        return Mono.just(assets);
    });
}

extractAllEnsuringEachElementExists

Extracts all entities, ensuring each key has a corresponding entity.

Signature:

Java
<T, F extends Serializable> Collection<T> extractAllEnsuringEachElementExists(
    GetResponse<T> getResponse,
    Set<F> keys,
    Function<T, F> getFieldFunction,
    APIError notFoundApiError
);

extractFieldForAll

Extracts a specific field from all entities in the response.

Signature:

Java
<T, F> Collection<F> extractFieldForAll(
    GetResponse<T> getResponse,
    Function<T, F> getFieldFunction
);

extractFieldForAll (PostResponse Collection)

Extracts a specific field from all entities in a batch POST response.

Signature:

Java
<T, F> Collection<F> extractFieldForAll(
    Collection<PostResponse<T>> postResponses,
    Function<T, F> getFieldFunction
);

extractEnsuringExists (PostResponse)

Extracts a value from a POST response, throwing an exception if the response is empty.

Signature:

Java
<R, T> R extractEnsuringExists(
    PostResponse<T> postResponse,
    Function<T, R> getValueFunction
);

Example:

Java
@Override
public Mono<Long> createReactive(final Asset asset) {
    final Mono<PostResponse<IdResponse>> resp = pvtAssetService.createAsset(asset);
    return resp.flatMap(idResponsePostResponse ->
        Mono.just(resourceExtractor.extractEnsuringExists(idResponsePostResponse,
            IdResponse::getId))
    );
}

extractEnsuringExists (GetSingleResponse)

Extracts the content from a single response, throwing an exception if empty.

Signature:

Java
<T> T extractEnsuringExists(GetSingleResponse<T> getSingleResponse);

Batch API Operations

This section provides complete examples for batch API operations, showing both the PvtService implementation (using PrivateApiHttpClient) and the corresponding DataManager implementation (using ResponseChecker and ResourceExtractor).

Overview

Batch API endpoints typically:

  • Use a /batch suffix in the URL (e.g., /workforce/calendars/r1/work-shift-exceptions/batch)

  • Accept a Collection of entities as the request body

  • Return different response types depending on the operation:

    • POST batch: Collection<PostResponse<IdResponse>> - one response per created entity

    • PATCH batch: PatchResponse - single response for the entire batch

    • DELETE batch: DeleteResponse - single response for the entire batch


POST Batch API

PvtService Implementation

Use this when: Creating a custom PvtService to call a POST batch endpoint.

Java
@Service
@RequiredArgsConstructor
public class PvtWorkShiftExceptionServiceImpl implements PvtWorkShiftExceptionService {

    private final PrivateApiHttpClient privateApiHttpClient;
    
    private static final String WORK_SHIFT_EXCEPTIONS_BATCH_API =
        "/workforce/calendars/r1/work-shift-exceptions/batch";

    @Override
    public Mono<Collection<PostResponse<IdResponse>>> batchCreate(
            final Collection<WorkShiftException> workShiftExceptions) {
        return privateApiHttpClient.postInBatchReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            IdResponse.class,
            Collection.class,
            workShiftExceptions);
    }
}

With URI Variables:

Java
private static final String WORK_ORDER_OPERATIONS_BATCH_API =
    "/work-orders/r1/work-orders/{workOrderId}/operations/batch";

@Override
public Mono<Collection<PostResponse<IdResponse>>> createWorkOrderOperationInBatch(
        final Long workOrderId,
        final Collection<WorkOrderOperation> workOrderOperations) {
    return privateApiHttpClient.postInBatchReactive(
        WORK_ORDER_OPERATIONS_BATCH_API,
        new Object[] {workOrderId},
        IdResponse.class,
        Collection.class,
        workOrderOperations);
}

DataManager Implementation

Use this when: Creating a custom DataManager to handle POST batch responses and extract created IDs.

Pattern 1: Validate all responses, then extract IDs

Java
@Component
@RequiredArgsConstructor
public class WorkShiftExceptionDataManagerImpl implements WorkShiftExceptionDataManager {

    private final PvtWorkShiftExceptionService pvtWorkShiftExceptionService;
    private final ResponseChecker responseChecker;
    private final ResourceExtractor resourceExtractor;

    @Override
    public Mono<Collection<Long>> createInBatchReactive(
            final Collection<WorkShiftException> workShiftExceptions) {
        final Mono<Collection<PostResponse<IdResponse>>> resp =
            pvtWorkShiftExceptionService.batchCreate(workShiftExceptions);

        return resp.flatMap(postResponses ->
            // First, validate all responses (throws exception if any has error)
            Flux.fromIterable(postResponses)
                .flatMap(responseChecker::throwIfResponseHasErrorReactive)
                // Then extract all IDs
                .then(Mono.just(
                    resourceExtractor.extractFieldForAll(postResponses, IdResponse::getId)))
        );
    }
}

Pattern 2: Extract IDs using stream (simpler, for when you don't need separate validation)

Java
@Override
public Mono<Collection<Long>> createInBatchReactive(final Long accountId,
                                                    final Collection<Meter> accountMeters) {
    final Mono<Collection<PostResponse<IdResponse>>> resp =
        pvtAccountMeterService.createAccountMetersInBatch(accountId, accountMeters);

    return resp.flatMap(postResponses ->
        Mono.just(postResponses.stream()
            .map(x -> resourceExtractor.extractEnsuringExists(x, IdResponse::getId))
            .toList())
    );
}

Pattern 3: Validate only (when you don't need the IDs)

Java
@Override
public Mono<Void> createInBatchReactive(final Long assetId,
                                        final Collection<AssetCharacteristic> assetCharacteristics) {
    final Mono<Collection<PostResponse<IdResponse>>> resp =
        pvtAssetCharacteristicService.createAssetCharacteristicsInBatch(assetId, assetCharacteristics);

    return resp.flatMap(postResponses ->
        Flux.fromIterable(postResponses)
            .flatMap(responseChecker::throwIfResponseHasErrorReactive)
            .then()
    );
}

PATCH Batch API

PvtService Implementation

Use this when: Creating a custom PvtService to call a PATCH batch endpoint.

Java
@Service
@RequiredArgsConstructor
public class PvtWorkShiftExceptionServiceImpl implements PvtWorkShiftExceptionService {

    private final PrivateApiHttpClient privateApiHttpClient;
    
    private static final String WORK_SHIFT_EXCEPTIONS_BATCH_API =
        "/workforce/calendars/r1/work-shift-exceptions/batch";

    @Override
    public Mono<PatchResponse> batchUpdate(
            final Collection<WorkShiftExceptionUpdate> workShiftExceptions) {
        return privateApiHttpClient.patchReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            Collection.class,
            workShiftExceptions);
    }
}

With URI Variables:

Java
private static final String WORK_ORDER_OPERATIONS_BATCH_API =
    "/work-orders/r1/work-orders/{workOrderId}/operations/batch";

@Override
public Mono<PatchResponse> patchWorkOrderOperationInBatch(
        final Long workOrderId,
        final Collection<WorkOrderOperationPatch> workOrderOperationPatches) {
    return privateApiHttpClient.patchReactive(
        WORK_ORDER_OPERATIONS_BATCH_API,
        new Object[] {workOrderId},
        Collection.class,
        workOrderOperationPatches);
}

DataManager Implementation

Use this when: Creating a custom DataManager to handle PATCH batch responses.

Java
@Component
@RequiredArgsConstructor
public class WorkShiftExceptionDataManagerImpl implements WorkShiftExceptionDataManager {

    private final PvtWorkShiftExceptionService pvtWorkShiftExceptionService;
    private final ResponseChecker responseChecker;

    @Override
    public Mono<Void> updateInBatchReactive(
            final Collection<WorkShiftExceptionUpdate> workShiftExceptions) {
        return pvtWorkShiftExceptionService.batchUpdate(workShiftExceptions)
            .flatMap(responseChecker::throwIfResponseHasErrorReactive);
    }
}

With URI Variables:

Java
@Override
public Mono<Void> updateInBatchReactive(final Long assetId,
                                        final Collection<AssetCharacteristicPatch> assetCharacteristicPatches) {
    return pvtAssetCharacteristicService.patchAssetCharacteristicsInBatch(assetId,
            assetCharacteristicPatches)
        .flatMap(responseChecker::throwIfResponseHasErrorReactive);
}

DELETE Batch API

PvtService Implementation

Use this when: Creating a custom PvtService to call a DELETE batch endpoint.

Java
@Service
@RequiredArgsConstructor
public class PvtWorkShiftExceptionServiceImpl implements PvtWorkShiftExceptionService {

    private final PrivateApiHttpClient privateApiHttpClient;
    
    private static final String WORK_SHIFT_EXCEPTIONS_BATCH_API =
        "/workforce/calendars/r1/work-shift-exceptions/batch";

    @Override
    public Mono<DeleteResponse> batchDelete(final DeleteFilters deleteFilters) {
        return privateApiHttpClient.deleteReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            deleteFilters);
    }
}

DataManager Implementation

Use this when: Creating a custom DataManager to handle DELETE batch responses.

Use DeleteFilters.singleParam() to specify which entities to delete by ID:

Java
import static overit.geocall.integrationapirest.http.request.DeleteFilters.singleParam;

@Component
@RequiredArgsConstructor
public class WorkShiftExceptionDataManagerImpl implements WorkShiftExceptionDataManager {

    private final PvtWorkShiftExceptionService pvtWorkShiftExceptionService;
    private final ResponseChecker responseChecker;

    @Override
    public Mono<Void> deleteReactive(final Collection<Long> workShiftExceptionIdList) {
        return pvtWorkShiftExceptionService.batchDelete(singleParam("id", workShiftExceptionIdList))
            .flatMap(responseChecker::throwIfResponseHasErrorReactive);
    }
}

Complete Batch API Example

Here's a complete example showing a PvtService and DataManager that support all three batch operations:

PvtService Interface

Java
public interface PvtWorkShiftExceptionService {

    Mono<Collection<PostResponse<IdResponse>>> batchCreate(
        Collection<WorkShiftException> workShiftExceptions);

    Mono<PatchResponse> batchUpdate(
        Collection<WorkShiftExceptionUpdate> workShiftExceptions);

    Mono<DeleteResponse> batchDelete(DeleteFilters deleteFilters);
}

PvtService Implementation

Java
@Service
@RequiredArgsConstructor
public class PvtWorkShiftExceptionServiceImpl implements PvtWorkShiftExceptionService {

    private final PrivateApiHttpClient privateApiHttpClient;
    
    private static final String WORK_SHIFT_EXCEPTIONS_BATCH_API =
        "/workforce/calendars/r1/work-shift-exceptions/batch";

    @Override
    public Mono<Collection<PostResponse<IdResponse>>> batchCreate(
            final Collection<WorkShiftException> workShiftExceptions) {
        return privateApiHttpClient.postInBatchReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            IdResponse.class,
            Collection.class,
            workShiftExceptions);
    }

    @Override
    public Mono<PatchResponse> batchUpdate(
            final Collection<WorkShiftExceptionUpdate> workShiftExceptions) {
        return privateApiHttpClient.patchReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            Collection.class,
            workShiftExceptions);
    }

    @Override
    public Mono<DeleteResponse> batchDelete(final DeleteFilters deleteFilters) {
        return privateApiHttpClient.deleteReactive(
            WORK_SHIFT_EXCEPTIONS_BATCH_API,
            new Object[] {},
            deleteFilters);
    }
}

DataManager Interface

Java
public interface WorkShiftExceptionDataManager {

    Mono<Collection<Long>> createInBatchReactive(
        Collection<WorkShiftException> workShiftExceptions);

    Mono<Void> updateInBatchReactive(
        Collection<WorkShiftExceptionUpdate> workShiftExceptions);

    Mono<Void> deleteReactive(Collection<Long> workShiftExceptionIdList);
}

DataManager Implementation

Java
import static overit.geocall.integrationapirest.http.request.DeleteFilters.singleParam;

@Component
@RequiredArgsConstructor
public class WorkShiftExceptionDataManagerImpl implements WorkShiftExceptionDataManager {

    private final PvtWorkShiftExceptionService pvtWorkShiftExceptionService;
    private final ResponseChecker responseChecker;
    private final ResourceExtractor resourceExtractor;

    @Override
    public Mono<Collection<Long>> createInBatchReactive(
            final Collection<WorkShiftException> workShiftExceptions) {
        final Mono<Collection<PostResponse<IdResponse>>> resp =
            pvtWorkShiftExceptionService.batchCreate(workShiftExceptions);

        return resp.flatMap(postResponses ->
            Flux.fromIterable(postResponses)
                .flatMap(responseChecker::throwIfResponseHasErrorReactive)
                .then(Mono.just(
                    resourceExtractor.extractFieldForAll(postResponses, IdResponse::getId)))
        );
    }

    @Override
    public Mono<Void> updateInBatchReactive(
            final Collection<WorkShiftExceptionUpdate> workShiftExceptions) {
        return pvtWorkShiftExceptionService.batchUpdate(workShiftExceptions)
            .flatMap(responseChecker::throwIfResponseHasErrorReactive);
    }

    @Override
    public Mono<Void> deleteReactive(final Collection<Long> workShiftExceptionIdList) {
        return pvtWorkShiftExceptionService.batchDelete(singleParam("id", workShiftExceptionIdList))
            .flatMap(responseChecker::throwIfResponseHasErrorReactive);
    }
}

Summary

By Customization Type

Customization Type

Component

When to Use

Custom PvtService

PrivateApiHttpClient

To execute HTTP calls (GET, POST, PUT, PATCH, DELETE) to Private API endpoints

Custom DataManager

ResponseChecker

To validate responses and throw exceptions on errors

Custom DataManager

ResourceExtractor

To extract entities from responses with validation

By Use Case

Use Case

Component

Method

Call Private API

PrivateApiHttpClient

getReactive, postReactive, patchReactive, putReactive, deleteReactive

Call Batch API

PrivateApiHttpClient

postInBatchReactive, patchReactive with Collection, deleteReactive with DeleteFilters

Check for errors

ResponseChecker

throwIfResponseHasErrorReactive

Extract single entity

ResourceExtractor

extractEnsuringItIsUnique, extractIfExists

Extract optional entity

ResourceExtractor

extractFirstIfExists, extractIfExistsEnsuringItIsUnique

Extract all entities

ResourceExtractor

extractAll, extractAllEnsuringEachElementIsUnique

Extract from POST

ResourceExtractor

extractEnsuringExists

Extract from batch POST

ResourceExtractor

extractFieldForAll(Collection<PostResponse<T>>)