Updated Dive Deeper (markdown)
parent
934b0762b5
commit
1fbac69890
@ -1 +1,83 @@
|
||||
TODO
|
||||
_In this page, the deeper understand of decorator will be handled._
|
||||
|
||||
# How basic decorators works?
|
||||
|
||||
In `nestlogged` package, there are three types of decorator.
|
||||
|
||||
1. Class Decorator (`LoggedInjectable`, `LoggedController`)
|
||||
2. Method Decorator (`LoggedFunction`, `LoggedRoute`, `ShouldScoped`)
|
||||
3. Parameter Decorator (`LoggedParam`, `InjectLogger`, `ScopeKey`)
|
||||
|
||||
There is a [good documentation](https://www.typescriptlang.org/docs/handbook/decorators.html) for this in typescriptlang.org.
|
||||
|
||||
# How does the logging decorator actually works?
|
||||
|
||||
In this section, the internal logic of the logging decorators are explained.
|
||||
|
||||
The main logic of this package is placed inside of method decorators.
|
||||
But before explaining about real logging decorators (method decorators), you have to understand the parameter decorator.
|
||||
|
||||
## Metadata Reflection
|
||||
|
||||
If you open the package.json file and see what is the dependency, there is a package `reflect-meatadata`.
|
||||
It is used by nestjs, but also nestlogged uses it very actively.
|
||||
All `LoggedParam`, `InjectLogger`, `ScopeKey` is powered by `reflect-metadata` package.
|
||||
|
||||
It provides **Metadata Reflection API**, which gives functionality to add additional metadatas to a class.
|
||||
It is pretty useful for saving the metadata in a decorator, and then use it in another decorator.
|
||||
|
||||
## `InjectLogger`, `LoggedParam`, `ScopeKey` Implementation Explained
|
||||
|
||||
If you look at `src/reflected.ts` file, there is implementations for `InjectLogger`, `LoggedParam`, `ScopeKey` decorators.
|
||||
What these decorators have in common is they store metadatas using metadata reflection api.
|
||||
|
||||
### `InjectLogger`
|
||||
|
||||
Let's look at `InjectLogger` function.
|
||||
|
||||
It's pretty small and simple.
|
||||
|
||||
What it does is putting the information of parameter to it's target.
|
||||
|
||||
When we put the `InjectLogger` to the parameter, the _the prototype of the class for an instance member_ (`target: any`), _The name of the member_ (`propertyKey: string | symbol`), and _The ordinal index of the parameter in the function’s parameter list_ (`parameterIndex: number`) are given to the `InjectLogger` function as the argument.
|
||||
|
||||
And call `Reflect.defineMetadata` to save the `parameterIndex` as `ScopedLogger` injection index.
|
||||
|
||||
The key (`scopedLogger`) when used to define metadata is defined at the almost top of the file, right bottom to the interfaces, as the constant symbol.
|
||||
|
||||
It will be used in both `LoggedFunction` and `LoggedRoute` which will explained later section.
|
||||
|
||||
### `LoggedParam`
|
||||
|
||||
At the right bottom to the `InjectLogger`, there is a function definition for `LoggedParam`.
|
||||
|
||||
It takes parameter name (`name: string`), and options for include or exclude path in object (`options?: {includePath?: ..., excludePath?: ...}`).
|
||||
|
||||
It returns parameter decorator function, which has same parameters with InjectLogger.
|
||||
|
||||
Since the decorator function is **returned after call**, it should be called to be applied.
|
||||
|
||||
```ts
|
||||
function a(
|
||||
@InjectLogger logger: ScopedLogger,
|
||||
@LoggedParam param: string // it's illegal, error
|
||||
@LoggedParam('param') param: string // Now it returns decorator function to be applied.
|
||||
) {}
|
||||
```
|
||||
|
||||
`LoggedParam` decorator can be used multiple time in one function.
|
||||
|
||||
Because of that, first thing decorator does is getting the existing decorator data.
|
||||
Right after that, push a new data, then redefine the metadata.
|
||||
|
||||
### `ScopeKey`
|
||||
|
||||
It is simillar to the `LoggedParam` decorator implementation.
|
||||
|
||||
The only different thing is, `ScopeKey` sorts its metadata array by priority.
|
||||
|
||||
### `ShouldScoped`
|
||||
|
||||
Although `ShouldScoped` is a method decorator, it only defined metadata like `InjectLogger`, and it's very simple.
|
||||
It just set `forceScopeKey` to true in method metadata.
|
||||
Getting the metadata value which is not defined is same as undefined, so the default value is falsy.
|
Loading…
x
Reference in New Issue
Block a user