@locustjs/services v1.1.1
@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.