loopback4-authorization
Version:
ARC authorization extension for loopback-next applications.
130 lines (97 loc) • 4.46 kB
Markdown
# Providers
This directory contains providers contributing additional bindings, for example
custom sequence actions.
## Overview
A [provider](http://loopback.io/doc/en/lb4/Creating-components.html#providers)
is a class that provides a `value()` function. This function is called `Context`
when another entity requests a value to be injected.
Here we create a provider for a logging function that can be used as a new
action in a custom [sequence](http://loopback.io/doc/en/lb4/Sequence.html).
The logger will log the URL, the parsed request parameters, and the result. The
logger is also capable of timing the sequence if you start a timer at the start
of the sequence using `this.logger.startTimer()`.
## Basic Usage
### TimerProvider
TimerProvider is automatically bound to your Application's
[Context](http://loopback.io/doc/en/lb4/Context.html) using the LogComponent
which exports this provider with a binding key of `extension-starter.timer`. You
can learn more about components in the
[related resources section](#related-resources).
This provider makes availble to your application a timer function which given a
start time _(given as an array [seconds, nanoseconds])_ can give you a total
time elapsed since the start in milliseconds. The timer can also start timing if
no start time is given. This is used by LogComponent to allow a user to time a
Sequence.
_NOTE:_ _You can get the start time in the required format by using
`this.logger.startTimer()`._
You can provide your own implementation of the elapsed time function by binding
it to the binding key (accessible via `ExtensionStarterBindings`) as follows:
```ts
app.bind(ExtensionStarterBindings.TIMER).to(timerFn);
```
### LogProvider
LogProvider can automatically be bound to your Application's Context using the
LogComponent which exports the provider with a binding key of
`extension-starter.actions.log`.
The key can be accessed by importing `ExtensionStarterBindings` as follows:
**Example: Binding Keys**
```ts
import {ExtensionStarterBindings} from 'HelloExtensions';
// Key can be accessed as follows now
const key = ExtensionStarterBindings.LOG_ACTION;
```
LogProvider gives us a seuqence action and a `startTimer` function. In order to
use the sequence action, you must define your own sequence as shown below.
**Example: Sequence**
```ts
class LogSequence implements SequenceHandler {
constructor(
(coreSequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
(coreSequenceActions.PARSE_PARAMS)
protected parseParams: ParseParams,
(coreSequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
(coreSequenceActions.SEND) protected send: Send,
(coreSequenceActions.REJECT) protected reject: Reject,
// We get the logger injected by the LogProvider here
(ExtensionStarterBindings.LOG_ACTION) protected logger: LogFn,
) {}
async handle(context: RequestContext) {
const {request, response} = context;
// We define these variable outside so they can be accessed by logger.
let args: any = [];
let result: any;
// Optionally start timing the sequence using the timer
// function available via LogFn
const start = this.logger.startTimer();
try {
const route = this.findRoute(request);
args = await this.parseParams(request, route);
result = await this.invoke(route, args);
this.send(response, result);
} catch (error) {
result = error; // so we can log the error message in the logger
this.reject(context, error);
}
// We call the logger function given to us by LogProvider
this.logger(request, args, result, start);
}
}
```
Once a sequence has been written, we can just use that in our Application as
follows:
**Example: Application**
```ts
const app = new Application({
sequence: LogSequence,
});
app.component(LogComponent);
// Now all requests handled by our sequence will be logged.
```
## Related Resources
You can check out the following resource to learn more about providers,
components, sequences, and binding keys.
- [Providers](http://loopback.io/doc/en/lb4/Creating-components.html#providers)
- [Creating Components](http://loopback.io/doc/en/lb4/Creating-components.html)
- [Using Components](http://loopback.io/doc/en/lb4/Using-components.html)
- [Sequence](http://loopback.io/doc/en/lb4/Sequence.html)
- [Binding Keys](http://loopback.io/doc/en/lb4/Decorators.html)