1.1.1 • Published 1 year ago

@locustjs/services v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

@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/services

Import

CommonJs

var { ServiceResponse } = require('@locustjs/services');

ES6

import { ServiceResponse } from '@locustjs/services'

ServiceResponse

Properties

PropertyTypeNullableDescription
successboolnowhether or not the operation was succesful
statusstringyes/nostatus of the operation
messagestringyesa message describing what happened/done/performed
messageKeystringyesa key that is used in translating current ServiceResponse and setting its message
messageArgsobjectyesan object that is used in translating current ServiceResponse
subjectstringyesa subject for the operation performed, helping receivers what current ServiceResponse is used for.
datedatetimenodate/time of the operation (issuance of current ServiceResponse instance)
dataanyyesdata returned by the service
exceptionobjectyesan error/exception object that may be thrown during the operation
innerResponsesArray<ServiceResponse>yesan array of inner ServiceResponses produced by inner services
infostringyesan optional extra data in the form of string returned by the service
bagobjectyesan optional extra data in the form of object returned by the service
logsArray<Log>yesan array of debugging Log messages generated by the service who issued current ServiceResponse

messageKey and messageArgs are used in translating ServiceResposne and providing locale-based message. logs is used in debugging mode (see @locustjs/servicemodel).

Methods

MethodDescription
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')); // true

Status 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.

MethodStatusIs Method
succeeded()succeededisSucceeded()
failed()failedisFailed()
faulted()faultedisFaulted()
defected()defectedisDefected()
flawed()flawedisFlawed()
errored()erroredisErrored()
stopped()stoppedisStopped()
abandoned()abandonedisAbandoned()
aborted()abortedisAborted()
rejected()rejectedisRejected()
refused()refusedisRefused()
quited()quitedisQuited()
exited()exitedisExited()
halted()haltedisHalted()
blocked()blockedisBlocked()
accessDenied()accessDeniedisAccessDenied()
notAuthenticated()notAuthenticatedisNotAuthenticated()
notAuthorized()notAuthorizedisNotAuthorized()
forbidden()forbiddenisForbidden()
notAllowed()notAllowedisNotAllowed()
notPermitted()notPermittedisNotPermitted()
notPossible()notPossibleisNotPossible()
notFound()notFoundisNotFound()
alreadyExists()alreadyExistsisAlreadyExists()
notValid()notValidisNotValid()
notProvided()notProvidedisNotProvided()
noData()noDataisNoData()
invalidData()invalidDataisInvalidData()
incorrectData()incorrectDataisIncorrectData()
inUse()inUseisInUse()
parentNotFound()parentNotFoundisParentNotFound()
parentExists()parentExistsisParentExists()
parentInvalid()parentInvalidisParentInvalid()
parentIncorrect()parentIncorrectisParentIncorrect()
parentNotValid()parentNotValidisParentNotValid()
parentInUse()parentInUseisParentInUse()
parentAccessDenied()parentAccessDeniedisParentAccessDenied()
childNotFound()childNotFoundisChildNotFound()
childExists()childExistsisChildExists()
childInvalid()childInvalidisChildInvalid()
childIncorrect()childIncorrectisChildIncorrect()
childNotValid()childNotValidisChildNotValid()
childInUse()childInUseisChildInUse()
childAccessDenied()childAccessDeniedisChildAccessDenied()
missingDependency()missingDependencyisMissingDependency()
invalidDependency()invalidDependencyisInvalidDependency()
incorrectDependency()incorrectDependencyisIncorrectDependency()

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()); // true

All 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-status

Fluent 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); // failed

ServiceResponse.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); // false

Status 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); // NotFound

The 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-found

Note that, ServiceResponse.statusSeparator does not affect existing ServiceResponse instances.

It is recommended to set customization using static properties in the begining of an application.