@locustjs/services
v1.1.1
Published
This library provides a `ServiceResponse` model, helping services implementing `Result Pattern` that is usable both in ront-end and back-end.
Readme
@locustjs/services
This library provides a ServiceResponse model, helping services implementing Result Pattern (front-end/back-end).
It supports both camel-case and pascal-case naming and provides status customization.
Install
npm i @locustjs/servicesImport
CommonJs
var { ServiceResponse } = require('@locustjs/services');ES6
import { ServiceResponse } from '@locustjs/services'ServiceResponse
Properties
| Property | Type | Nullable | Description |
|----------------|----------------------------|----------|-------------|
| success | bool | no | whether or not the operation was succesful |
| status | string | yes/no | status of the operation |
| message | string | yes | a message describing what happened/done/performed |
| messageKey | string | yes | a key that is used in translating current ServiceResponse and setting its message |
| messageArgs | object | yes | an object that is used in translating current ServiceResponse |
| subject | string | yes | a subject for the operation performed, helping receivers what current ServiceResponse is used for. |
| date | datetime | no | date/time of the operation (issuance of current ServiceResponse instance) |
| data | any | yes | data returned by the service |
| exception | object | yes | an error/exception object that may be thrown during the operation |
| innerResponses | Array<ServiceResponse> | yes | an array of inner ServiceResponses produced by inner services |
| info | string | yes | an optional extra data in the form of string returned by the service |
| bag | object | yes | an optional extra data in the form of object returned by the service |
| logs | Array<Log> | yes | an array of debugging Log messages generated by the service who issued current ServiceResponse |
messageKeyandmessageArgsare used in translatingServiceResposneand providing locale-basedmessage.logsis used in debugging mode (see @locustjs/servicemodel).
Methods
| Method | Description |
|-----------------|-|
| copy(obj) | copies given obj to current instance (normally used to copy one ServiceResponse to another) |
|toJson(spacer)| serializes current instance to json (ignoring empty fields) |
|setStatus(status, message, ex)| sets status, message and exception properties with given arguments |
| is(status)| checks whether status property equals status argument. |
| setData(data)| sets data to the given data argument and returns current instance. |
| setException(ex)| sets exception to the given ex argument and returns current instance. |
| setInfo(info)| sets info to the given info argument and returns current instance. |
| setSubject(subject)| sets subject to the given subject argument and returns current instance. |
| setBag(bag)| sets bag to the given bag argument and returns current instance. |
| setMessageKey(key)| sets messageKey to the given key argument and returns current instance. |
| setArgs(args)| sets messageArgs to the given args object and returns current instance. |
| addArg(args)| merges and adds args object to messageArgs and returns current instance. |
| addArg(key, value)| adds a key/value pair to messageArgs object and returns current instance. |
| addResponse(res, subject)| adds res object to innerResponse array and returns current instance. res must be a ServiceResponse object. If subject argument is specified, the subject prop in res object will be set to that argument. |
Example:
const sr = new ServiceResponse();
sr.setStatus('failed')
console.log(sr); // { success: true, status: "failed", date: "2024-12-13 13:45:07" }
console.log(sr.is('failed')); // trueStatus Methods
In order to ease working with ServiceResponse and making it more friendly, a list of instance methods are provided that set the status property with specific values. For every method, there is a corresponding is method that testifies whether status of the current ServiceResponse instance matches the method name.
| Method | Status | Is Method |
|-------------------------|---------------------|--------------------------|
| succeeded() | succeeded | isSucceeded() |
| failed() | failed | isFailed() |
| faulted() | faulted | isFaulted() |
| defected() | defected | isDefected() |
| flawed() | flawed | isFlawed() |
| errored() | errored | isErrored() |
| stopped() | stopped | isStopped() |
| abandoned() | abandoned | isAbandoned() |
| aborted() | aborted | isAborted() |
| rejected() | rejected | isRejected() |
| refused() | refused | isRefused() |
| quited() | quited | isQuited() |
| exited() | exited | isExited() |
| halted() | halted | isHalted() |
| blocked() | blocked | isBlocked() |
| accessDenied() | accessDenied | isAccessDenied() |
| notAuthenticated() | notAuthenticated | isNotAuthenticated() |
| notAuthorized() | notAuthorized | isNotAuthorized() |
| forbidden() | forbidden | isForbidden() |
| notAllowed() | notAllowed | isNotAllowed() |
| notPermitted() | notPermitted | isNotPermitted() |
| notPossible() | notPossible | isNotPossible() |
| notFound() | notFound | isNotFound() |
| alreadyExists() | alreadyExists | isAlreadyExists() |
| notValid() | notValid | isNotValid() |
| notProvided() | notProvided | isNotProvided() |
| noData() | noData | isNoData() |
| invalidData() | invalidData | isInvalidData() |
| incorrectData() | incorrectData | isIncorrectData() |
| inUse() | inUse | isInUse() |
| parentNotFound() | parentNotFound | isParentNotFound() |
| parentExists() | parentExists | isParentExists() |
| parentInvalid() | parentInvalid | isParentInvalid() |
| parentIncorrect() | parentIncorrect | isParentIncorrect() |
| parentNotValid() | parentNotValid | isParentNotValid() |
| parentInUse() | parentInUse | isParentInUse() |
| parentAccessDenied() | parentAccessDenied | isParentAccessDenied() |
| childNotFound() | childNotFound | isChildNotFound() |
| childExists() | childExists | isChildExists() |
| childInvalid() | childInvalid | isChildInvalid() |
| childIncorrect() | childIncorrect | isChildIncorrect() |
| childNotValid() | childNotValid | isChildNotValid() |
| childInUse() | childInUse | isChildInUse() |
| childAccessDenied() | childAccessDenied | isChildAccessDenied() |
| missingDependency() | missingDependency | isMissingDependency() |
| invalidDependency() | invalidDependency | isInvalidDependency() |
| incorrectDependency() | incorrectDependency | isIncorrectDependency() |
Example:
const sr = new ServiceResponse();
sr.failed()
console.log(sr); // { success: true, status: "failed", date: "2024/12/06 08:11:35" }
console.log(sr.isFailed()); // trueAll the methods set success to false and have a signature as below:
method(message, ex)The only exception is succeeded() method that sets success to true and its signature is as below:
succeeded(data, message)There is a static ServiceResponse.fromStatus(status) method that returns a new ServiceResponse instance whose status is set using the argument passed to fromStatus().
const sr = ServiceResponse.fromStatus('my-status');
console.log(sr.status); // my-statusFluent methods
All stuas methods return current ServiceResponse instance. In addition, ServiceResponse provides a set of instance methods that enable fluent way of setting props on a ServiceResponse instance by chaining them together.
Example:
const sr = new ServiceResponse();
sr.failed()
.setException(ex)
.setMessageKey('my-service.my-action')
.addArg('name', 'John Doe')
.addResponse(ServiceResponse.invalidParent(), 'addParent');Customization
Casing of Properties
As it is said, it is possible to use ServiceResponse both in pascal-case and camel-case. By default, ServiceResponse uses camel-case naming. In order to use pascal-casing there are two ways.
usePascalProps
We can set usePascalProps instance prop to true in a ServiceResponse instance. The ServiceResponses properties will instantly change to pascal-case.
const sr = new ServiceResponse();
// sample status
sr.failed();
console.log(sr.status); // failed
console.log(sr.toJson()); // { "success": false, "status": "failed", "date": "2024-12-13 08:49:32" }
sr.usePascalProps = true;
console.log(sr.status); // undefined
console.log(sr.Status); // failed
console.log(sr.toJson()); // { "Success": false, "Status": "failed", "Date": "2024-12-13 08:49:32" }
sr.usePascalProps = false;
console.log(sr.Status); // undefined
console.log(sr.status); // failed
console.log(sr.toJson()); // { "success": false, "status": "failed", "date": "2024-12-13 08:49:32" }This property only affects a single instance.
Note: The instance
copy()method, is a smart method and distinguishes casing in current instance and given instance.
const sr1 = new ServiceResponse();
const sr2 = new ServiceResponse();
sr2.usePascalProps = true;
sr1.failed();
sr2.copy(sr1);
console.log(sr2.status); // undefined
console.log(sr2.Status); // failedServiceResponse.usePascalProps
We can also set the static ServiceResponse.usePascalProps to true. The effect of this setting is global and affects all newly instantiated ServiceResponse objects.
const sr1 = new ServiceResponse();
const sr2 = new ServiceResponse();
console.log(sr1.status === undefined); // false
console.log(sr1.Status === undefined); // true
console.log(sr2.status === undefined); // false
console.log(sr2.Status === undefined); // true
ServiceResponse.usePascalProps = true;
const sr3 = new ServiceResponse();
const sr4 = new ServiceResponse();
console.log(sr3.status === undefined); // true
console.log(sr4.Status === undefined); // false
console.log(sr3.status === undefined); // true
console.log(sr4.Status === undefined); // falseStatus casing
By default, ServiceResponse uses camel-casing in its intrinsic statuses, like notfound, accessdenied. We can change this to pascal-casing by setting the static ServiceResponse.usePascalStatus to true.
const sr1 = new ServiceResponse();
sr1.notFound();
console.log(sr1.status); // notfound
ServiceResponse.usePascalStatus = true;
const sr2 = new ServiceResponse();
sr2.notFound();
console.log(sr2.status); // NotFoundThe effect of this seting is global. It affects all ServiceResponse objects that are newly created.
Status separator
Using the static ServiceResponse.statusSeparator, we can specify a separator in status values.
const sr1 = new ServiceResponse();
sr1.notFound();
console.log(sr1.status); // notfound
ServiceResponse.statusSeparator = "-";
const sr2 = new ServiceResponse();
sr2.notFound();
console.log(sr2.status); // not-foundNote that, ServiceResponse.statusSeparator does not affect existing ServiceResponse instances.
It is recommended to set customization using static properties in the begining of an application.
