Skip to content

Commit 7887bc6

Browse files
authored
Update README.md
1 parent a577c8e commit 7887bc6

File tree

1 file changed

+25
-33
lines changed

1 file changed

+25
-33
lines changed

README.md

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
---
4545

4646
- [Purpose](#purpose)
47-
* [Easy Consistency as Toolings](#easy-consistency-as-toolings)
48-
* [Business Logic as Self-Expanatory Code](#business-logic-as-self-expanatory-code)
47+
* [Automated Observability and Error Handling](#automated-observability-and-error-handling)
48+
* [Self-Expanatory Business Logic](#self-expanatory-business-logic)
4949
* [JavaScript Decorators At Its Best](#javascript-decorators-at-its-best)
5050
- [How to Use](#how-to-use)
5151
* [Install](#install)
@@ -55,7 +55,6 @@
5555
* [Extension](#extension)
5656
* [Opinionated Function Signature](#opinionated-function-signature)
5757
* [Refactor](#refactor)
58-
* [Without Decorator and Pipe Operators](#without-decorator-and-pipe-operators)
5958
- [Integration](#integration)
6059
* [Integrate with Server Frameworks](#integrate-with-server-frameworks)
6160
* [Integrate with Redux](#integrate-with-redux)
@@ -66,9 +65,9 @@
6665

6766
### Purpose
6867

69-
#### Easy Consistency as Toolings
68+
#### Automated Observability and Error Handling
7069

71-
By packing all standardisable patterns such as observarability, error handling, etc. as reusable decorators, it promotes and ensures consistency across micro-services and teams. This greatly improves the monitor efficiency and debugging or maintainance experience.
70+
By packing all standardisable patterns such as observarability, error handling, etc. as reusable decorators, it promotes and ensures consistency across micro-services and teams. This greatly improves the monitor clarity and debugging/maintainance experience.
7271

7372

7473
```js
@@ -92,26 +91,40 @@ class SubscriptionAPI
9291
/* handler.js - an illustration of the business logic */
9392
import { UserProfileAPI, SubscriptionAPI } from './api.js';
9493

95-
/**
96-
@param {string} param.userId
97-
**/
9894
export const userCancelSubscription = ({ userId }, meta, context)
9995
|> UserProfileAPI.getSubscription
10096
|> SubscriptionAPI.cancel
10197

10298
```
99+
> Thanks to the [opionated function signature](#opinionated-function-signature), those decorators work out of box with minimum configuration to create a calling stack tree using the exact names of the decorated functions, producing structured log, metrics, tracing.
103100
104-
The structured log it produced below makes it a breeze to precisely pinpoint the error function with param to reproduce the case. This can be easily further integrated into an automated cross-team monitoring and alerting system.
101+
The structured log it produced below makes it a breeze to precisely pinpoint the error function with param to reproduce the case. This can be easily further integrated into an automated cross-team monitoring and alerting/debugging system.
105102

106103
```shell
107104
[info] event: userCancelSubscription.getSubscription
108105
[error] event: userCancelSubscription.cancelSubscription, type: TimeoutError, Retry: 1, Param: { subscriptionId: '4672c33a-ff0a-4a8c-8632-80aea3a1c1c1' }
109106
```
110107
111-
> Those decorators work out of box with minimum configuration thanks to the [opionated function signature](
112-
#opinionated-function-signature). They also work nicely [without @, |> operators](#without-decorator-and-pipe-operators).
108+
> We are calling those decorators **hooks(decorators at call-time beside definition-time)** to indicate that they can be used at any point of a business logic function lifecycle to extend highly flexible and precise control.
109+
110+
```js
111+
/* handler.js - configure and attach hooks to business logic steps with hookEachPipe */
112+
import { pipeHookEach, eventLogger, eventTimer } from '@opbi/hooks';
113+
import { UserProfileAPI, SubscriptionAPI } from './api.js';
114+
115+
export const userCancelSubscription = async pipeHookEach(
116+
// all with default configuration applied to each step below
117+
eventLogger(), eventTimer()
118+
)(
119+
UserProfileAPI.getSubscription,
120+
// precise control with step only hook
121+
chain(
122+
errorRetry({ condition: e => e.type === 'TimeoutError' })
123+
)(SubscriptionAPI.cancel),
124+
);
125+
```
113126
114-
#### Business Logic as Self-Expanatory Code
127+
#### Self-Expanatory Business Logic
115128
116129
By abstract out all common control mechanism and observability code into well-tested, composable decorators, this also helps to achieve codebase that is self-explanatory of its business logic and technical behaviour by the names of functions and decorators. This is great for testing and potentially rewrite the entire business logic functions as anything other than business logic is being packed into well-tested reusable decorators, which can be handily mocked during test.
117130
@@ -189,27 +202,6 @@ function (param, meta, context) {}
189202
#### Refactor
190203
To help adopting the hooks by testing them out with minimal refactor on non-standard signature functions, there's an unreleased [adaptor](https://github.com/opbi/toolchain/blob/adapator-non-standard/src/hooks/adaptors/nonstandard.js) to bridge the function signatures. It is not recommended to use this for anything but trying the hooks out, especially observability hooks are not utilised this way.
191204
192-
#### Without Decorator and Pipe Operators
193-
194-
> We are calling those decorators **hooks(decorators at call-time beside definition-time)** to indicate that they can be used at any point of a business logic function lifecycle to extend highly flexible and precise control.
195-
196-
```js
197-
/* handler.js - configure and attach hooks to business logic steps with hookEachPipe */
198-
import { pipeHookEach, eventLogger, eventTimer } from '@opbi/hooks';
199-
import { UserProfileAPI, SubscriptionAPI } from './api.js';
200-
201-
export const userCancelSubscription = async pipeHookEach(
202-
// all with default configuration applied to each step below
203-
eventLogger(), eventTimer()
204-
)(
205-
UserProfileAPI.getSubscription,
206-
// precise control with step only hook
207-
chain(
208-
errorRetry({ condition: e => e.type === 'TimeoutError' })
209-
)(SubscriptionAPI.cancel),
210-
);
211-
```
212-
213205
---
214206
### Integration
215207

0 commit comments

Comments
 (0)