Begin Here

KOS Data Services

Introduction

As a KOS model proceeds through its lifecycle there are hooks where it makes sense to hydrate the model with a baseline set of data from the backend.

Typically, models use a "baseline and delta" approach where models are populated with an initial set of data and then updated via events published through the WebSocket transport.

Data Services provide a useful pattern for managing the initial hydration phase and are typically called in either the loading or activate lifecycle hooks on the model.

Service Factory

The KOS SDK exposes a ServiceFactory utility that provides access to some common data access functions that simplify interactions with the KOS backend

const { getOne } = ServiceFactory.build({
  destinationAddress: "",
  basePath: `${URL}/foo`,
});

The Service Factory will provide a number of useful functions including:

  • getOne: perform a GET operation that will return a single object

  • getAll: similar to getOne with the difference being that the operation is expected to return a collection of items.

  • deleteModel: perform a DELETE operation that will remove a given model from the backend.

  • postModel: perform a POST operation that will add a given model to the backend

  • putModel: perform a PUT operation that will modify an existing model

Service Factory Initialization

The Service Factory can be initialized with some configuration data to provide default behavior to the returned helper functions.

  • basePath: the root path where all operations will be executed. This can be overridden on a per-operation basis.

  • getAllPath: overrides the base path for all calls to getAll.

  • getOnePath: overrides the base path for all calls to getOne.

  • deleteModelPath: overrides the base path for all calls to deleteModel.

  • addModelPath: overrides the base path for all calls to postModel.

  • modifyModelPath: overrides the base path for all calls to putModel.

all of these paths can be further overridden at the time the function is called as well

Service Functions

A service module will export one or more services that can be invoked at the model layer.

For example, in the demo project, there is a basic service that will fetch the details for our newly created Demo Model.

// src/models/demo/services/demo-services.ts

import {resolveServiceUrl, ServiceFactory} from "@coca-cola/kos-ui-core";

const { URL } = resolveServiceUrl("DEMO_SERVICE");
const { getOne } = ServiceFactory.build({
  destinationAddress: "",
  basePath: `${URL}/foo`,
});

// interface for the Model Data Transfer Object.  This is independent of the model specification as there are frequently subtle differences between the data received from the backend and how it is represented in the model.

interface DemoResponse {
  id: string;
  name: string;
}
/**
 * @category Service
 * Retrieves a single demo model
 */
export const getDemo = async (id: string) => {
  // Overriding the URL to append the passed in model ID.

  const response = await getOne<DemoResponse>({
    urlOverride: `${URL}/foo/${id}`,
  });
  return response;
};

Usage in a model

A KOS model can either import the service directly OR pass it in via the model Options depending on your requirements. In cases where a single model might need access to different services depending on the context, passing them in via the options provides a decoupled Inversion Of Control (IoC) option. This is also useful for isolated testing where it can be preferable to inject mock services rather than executing against the live backend. For basic cases, you can just import the service directly.

In the demo model the load lifecycle hook is an appropriate location to invoke the service and update the model:

// src/models/demo/demo-model.ts

import {getDemo} from "./services/demo-services";

...

   async load(): Promise<void> {
        try {
            log.info("loading demo model");
            const response = await getDemo(this.id);
            log.debug(`received response ${response}`);

            // In async cases, use the kosAction wrapper to provide a
            // stable closure that can reliably update the model
            kosAction(() => {
                const newName = response?.data.name;
                if (newName) {
                    this.name = newName;
                }
            });
        } catch(e) {
            log.error(e);
            throw e;
        }

    }
Previous
Next
On this page
Java Development
Seamlessly transition from Legacy+ systems to Freestyle microdosing and advanced distributed dispense systems.
UI Development
Using KOS SDKs, integrating Consumer and Non-consumer facing UIs becomes seamless, giving you less hassle and more time to create.
Video Library
Meet some of our development team, as they lead you through the tools, features, and tips and tricks of various KOS tools.
Resources
Familiarize yourself with KOS terminology, our reference materials, and explore additional resources that complement your KOS journey.
Copyright © 2024 TCCC. All rights reserved.