Service Reference
Services act as a repository of accessible behavior and data, and can be used for a variety of purposes, from implementing commands and operations, to managing shared data, to interfacing with the REST API of an external service.
Service Registration
All services need to be registered with VertiGIS Studio Web. Services can optionally use the itemType
property to bind to an item in the app config.
export default function(registry: LibraryRegistry) {
...
registry.registerService({
id: "custom-service",
getService: (config) => new CustomService(config),
// Use this setting if you want your service to load an
// item from the app config.
itemType: "custom-service-model",
// Use this setting if you want your service to load on
// application startup. Defaults to `false`.
loadOnStartup: true,
})
...
}
Service Lifecycle
On application load, all services that are configured to automatically load on startup are created and initialized in parallel, along with core services like the message bus.
All other services are created and initialized (i.e. the _onInitialize
method is called) when they are first invoked. This can happen in multiple ways.
- If a command or operation implemented by the service is executed, then the service will be created and initialized to run that command.
- If a different component or service injects the service, then the service will be created and initialized to fulfill that dependency.
Services are destroyed (i.e. the _onDestroy
method is invoked) when the application is destroyed.
Service Anatomy
All services have access to initialization and cleanup methods, as well as the messages
property that allows for the registration and execution of commands and operations.
Initialization and Cleanup
Sometimes, a service is required to perform initialization and cleanup actions, for example, to initialize dynamic data and cleanup dangling references. The ServiceBase
class has two methods to achieve this:
_onInitialize()
, which can be overridden with additional initialization logic,- and
_onDestroy()
, which can be overridden to facilitate cleanup.
The following service uses these methods to subscribe to an event and cleanup the event handler afterwards.
Always call super._onInitialize()
before any custom initialization logic.
import { ServiceBase } from "@vertigis/web/services";
import { MapEvent } from "@vertigis/viewer-spec/messaging/registry/map";
export default class CustomService extends ServiceBase {
handles: IHandle[] = [];
protected async _onInitialize(): Promise<void> {
await super._onInitialize();
this.handles.push(
this.messages.events.map.initialized.subscribe(
(e: MapEvent) => {
console.log(
"Map Initialized, do your map dependent model setup here."
);
}
)
);
}
protected async _onDestroy(): Promise<void> {
await super._onDestroy();
this.handles.forEach((h) => h.remove());
}
}
Message Bus
All services have access to the messages
property on the class instance, which gives access to all commands, operations, and events in the application.
Models and Configuration
Like components, services can be configured through the app config. A service can participate in the config by extending the ConfigurableServiceBase
class. For more information on the relationship between services and configuration, check out this article. The following example demonstrates a service with one configurable property, name
.
The service is linked to the config through the itemType
and id
properties.
- Service
- Registration
- App Config
export interface CustomServiceProperties
extends ServiceModelProperties {
name: string;
}
@serializable
export default class CustomServiceWithConfig extends ConfigurableServiceBase<CustomServiceProperties> {
id: "my-unique-id";
name: string;
async sayHello(): Promise<string> {
return `Hello, ${this.name}`;
}
protected _getSerializableProperties(): PropertyDefs<CustomServiceProperties> {
return {
...super._getSerializableProperties(),
name: {
serializeModes: ["initial"],
default: "Ian",
},
};
}
}
export default function (registry: LibraryRegistry) {
registry.registerService({
id: "custom-service",
title: "Custom Service",
getService: (config) => new CustomServiceWithConfig(config),
itemType: "custom-service-model",
});
}
{
"schemaVersion": "1.0",
"items": [
{
"$type": "custom-service-model",
"id": "my-unique-id",
"name": "Noah"
}
]
}
Next Steps
Learn how to use Commands and Operations with Services
Learn how to run and implement commands and operations with custom services
Learn about Service Interactions
Learn about how services can directly interact through dependency injection
Build a Custom Command with a Custom Service
Follow a step by step guide to building a custom command with a custom service
Build a Service that Manages Dynamic Data
Built a service that manages a dynamic data source and exposes it to components