Skip to main content

Service Architecture and usage

Introduction

Elevate uses a Service Architecture to ensure applications uses an unified way of access data independent of what way the data is provided into the application.

You can find documentation of the General Service Architecture of Elevate on the Elevate Confluence Services pages.

This architecture is defined in two main layers: Service, which acts as implementation contract for the Providers and Providers which implements the Service contract for specific data providers.

Then the Data Models are the definition of the expected data from the application in order to display the data. For the Providers to follow the expected data models, a parsing process is needed inside such Providers.

Last, but not least, we have the Service Manager, which acts as a single definition point for Service and Provider on the application and also will return the proper Provider for a given Service to be used in the application.

Benefits of this model

  • Clear responsibility definition.
    • Provider definition and use (Service Manager)
    • Contract definition (Service)
    • Implementation (Provider)
    • Parsing (Provider)
  • Well typed and with proper data definition, so easy to understand what the app should use and how
  • Easy to extend.
  • Reusability of Business Logic.
  • Easy to create new shared providers, i.e middleware, Brightcove.
  • Easy to switch from one provider to another.
  • Almost 0 human-error-prone.

Usage

Usage on Server Components

Usage on Client Components

Usage sample

note

Note: First, you need to setup your Application Services config by updating src/services/config.ts serviceConfig object, which is exported and used by src/services/manager.ts

Initialization

info

Init is done based on serviceConfig from src/services/config.ts so you need to review that file to update Service setup

import { ServiceManager } from '@/services/manager';
import { serviceConfig } from '@/services/config';
[...]
ServiceManager.init(serviceConfig);

Service Usage

import { ServiceManager } from '@/services/manager';
[...]
const serviceManager = ServiceManager.getInstance();
const { provider: configProvider } = serviceManager.getService('config');
await configProvider.getConfig();

Customization

This architecture is intended to allow customization but keeping in mind the following points:

  • New providers can be added, but needs to follow the Service Interface contract on two levels:
    • Service contract methods, naming, parameters, ...
    • Provider returning Data Model
  • If your application needs to update the contract, it can be updated on either the Service (adding methods, removing unused ones) and also on the Data Models (adding fields, removing fields), but keep it mind the application usage of such Services.