@hitachivantara/app-shell-services
v2.0.2
Published
AppShell Services
Keywords
Readme
@hitachivantara/app-shell-services
Hitachi Vantara App Shell Services. Support package to manage services at the App Shell ecosystem.
Overview
This package provides service management capabilities including:
- Service registration and resolution
- React hooks for service consumption
- Type-safe service interfaces
Usage
Services supports a consumer/provider model where:
- Consumers, like an app owning a header action for example, will consume a given service contract either from the shared-services package from other app or, if also a provider, its own shared-services package. The services are identified by an
idthat, ideally, should be unique while also providing information about the type it expects likemain-app:AppsMetadata. This way, the consumers know the type they expect and the providers know what to implement, without collisions in the multi-tenant App Shell ecosystem. - Providers implement services that match the consumer's contract and register them under the consumer's
idin itsapp-shell.config.tsfile as example below:
services: {
"@some-package/main-app-services:AppsMetadata": [{
instance: {
value: {
name: "dummy app",
description: "This is 'dummy app' description",
version: 2.0,
final: false,
}
}
}],
}This way, looking at the configuration, it is clear that there is a consumer application (main-app) that expects service-providers to implement the AppsMetadata contract and register them under its @some-package/main-app-services:AppsMetadata service definition, keeping the consumer resilient: as long as service-providers adhere to the declared contract the consumer code will not break.
Example (consumer)
Exploring the example above, the consumer should register the service contract and definition in a package that can be shared between the consumer and the provider:
// @some-package/main-app-services
export type AppsMetadata = {
appId: string;
appName: string;
version: number;
isRelease: boolean;
};
/**
* Service definitions that the consumer 'main app' exposes on a services shared package.
*/
export const MainAppServiceDefinitions = {
/**
* The {@const AppsMetadata} service represents the service-provider application metadata.
*
* The service-providers that implement this contract will have its implementation displayed on a page.
*
* Instances of this service are typescript constants of type {@link AppsMetadata}.
*/
AppsMetadata: {
id: "@some-package/main-app-services:AppsMetadata",
},
};The main app consumes all the service definitions under its identifier using the useServices hook, which returns all the successfully loaded services of the requested identifier, namely the MainAppServiceDefinitions.AppsMetadata service definition.
This way, as long as any provider implements and registers a service that matches the AppsMetadata contract, it will be safe to render as expected:
const AboutApps: FC = () => {
const { services: appsMetadata[], isPending, error } = useServices<AppsMetadata[]>(
ServiceDefinitions.AppsMetadata.id,
);
if (isPending) {
return <HvLoading>Loading apps metadata from services...</HvLoading>;
}
if (error) {
const errorMessage = `Failed to apps metadata: ${ServiceDefinitions.AppsMetadata.id}`;
return <HvTypography>{errorMessage}</HvTypography>;
}
return (
<HvContainer maxWidth="lg">
<HvTypography variant="title1">Applications information</HvTypography>
<HvGrid container spacing={3}>
{appsMetadata.map((metadata, index) => {
return (
<HvGrid item key={metadata.appId}>
<HvTypography>
<strong>Application: </strong> {metadata.appName}
</HvTypography>
<HvTypography>
{metadata.version} - {metadata.isRelease ? "Release" : "In development"}
</HvTypography>
</HvGrid>
);
})}
</HvGrid>
</HvContainer>
);
};Example (provider)
A simple way to implement a service-provider that matches the AppsMetadata contract is a constant like below:
import { AppsMetadata } from "@some-package/main-app-services";
const dummyAppMetadata: AppsMetadata = {
appId: "ProviderApp",
appName: "A provider app",
version: 1.0,
isRelease: true,
};and having it registered on its app-shell.config.ts file, under the consumer service identifier.
//...
services: {
"@some-package/main-app-services:AppsMetadata": [
{
instance: {
bundle: "dummy-app/metadata/dummyAppMetadata.js",
},
ranking: 100,
}
],
},
//...More examples
To see more examples, please check the Default App ServicesDemo page and the app-shell.config.ts file.
Installation
The App Shell Services is available as an NPM package, and can be installed with:
npm install @hitachivantara/app-shell-services