Description
The persistence components are of two types. The first type is a basic one that can be used with any kinds of objects and offers only a minimal set of operations. The second type is known as “identifiable” persistence and is designed to work specifically with data objects that have a unique ID field. This type provides a complete set of CRUD operations, which covers the most common scenarios for managing data effectively.
Packages
The module contains the following packages:
- Read - generic data reading interfaces.
- Write - generic data writing interfaces.
- Persistence - in-memory and file persistence components, as well as JSON persister class.
Use
Install the NPM package as
npm install pip-services3-persistence-node --save
As an example, lets implement persistence for the following data object.
import { IIdentifiable } from 'pip-services3-commons-nodex';
export class MyObject implements IIdentifiable {
public id: string;
public key: string;
public value: number;
}
Our persistence component shall implement the following interface with a basic set of CRUD operations.
export interface IMyPersistence {
getPageByFilter(correlationId: string, filter: FilterParams, paging: PagingParams): Promise<DataPage<MyObject>>;
getOneById(correlationId: string, id: string): Promise<MyObject>;
getOneByKey(correlationId: string, key: string): Promise<MyObject>
create(correlationId: string, item: MyObject): Promise<MyObject>;
update(correlationId: string, item: MyObject): Promise<MyObject>;
deleteById(correlationId: string, id: string): Promise<MyObject>;
}
To implement in-memory persistence component you shall inherit IdentifiableMemoryPersistence
.
Most CRUD operations will come from the base class. You only need to override getPageByFilter
method with a custom filter function.
And implement a getOneByKey
custom persistence method that doesn’t exist in the base class.
import { IdentifiableMemoryPersistence } from 'pip-services3-data-nodex';
export class MyMemoryPersistence extends IdentifableMemoryPersistence {
public constructor() {
super();
}
private composeFilter(filter: FilterParams): any {
filter = filter || new FilterParams();
let id = filter.getAsNullableString("id");
let tempIds = filter.getAsNullableString("ids");
let ids = tempIds != null ? tempIds.split(",") : null;
let key = filter.getAsNullableString("key");
return (item) => {
if (id != null && item.id != id)
return false;
if (ids != null && ids.indexOf(item.id) < 0)
return false;
if (key != null && item.key != key)
return false;
return true;
};
}
public async getPageByFilter(correlationId: string, filter: FilterParams, paging: PagingParams): Promise<DataPage<MyObject>> {
return await super.getPageByFilter(correlationId, this.composeFilter(filter), paging, null, null);
}
public async getOneByKey(correlationId: string, key: string): Promise<MyObject> {
let item = this._items.find(item => item.key == key);
if (item != null) {
this._logger.trace(correlationId, "Found object by key=%s", key);
} else {
this._logger.trace(correlationId, "Cannot find by key=%s", key);
}
return item;
}
}
It is easy to create file persistence by adding a persister object to the implemented in-memory persistence component.
import { ConfigParams } from 'pip-services3-commons-nodex';
import { JsonFilePersister } from 'pip-services3-data-nodex';
export class MyFilePersistence extends MyMemoryPersistence {
protected _persister: JsonFilePersister<MyObject>;
constructor(path?: string) {
super();
this._persister = new JsonFilePersister<MyObject>(path);
this._loader = this._persister;
this._saver = this._persister;
}
public configure(config: ConfigParams) {
super.configure(config);
this._persister.configure(config);
}
}
Configuration for your microservice that includes memory and file persistence may look the following way.
...
{{#if MEMORY_ENABLED}}
- descriptor: "myservice:persistence:memory:default:1.0"
{{/if}}
{{#if FILE_ENABLED}}
- descriptor: "myservice:persistence:file:default:1.0"
path: {{FILE_PATH}}{{#unless FILE_PATH}}"../data/data.json"{{/unless}}
{{/if}}
...