Skip to content

Latest commit

 

History

History

providers

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Providers

This directory contains providers contributing additional bindings, for example custom sequence actions.

Overview

A provider 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.

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

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:

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

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

class LogSequence implements SequenceHandler {
  constructor(
    @inject(coreSequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
    @inject(coreSequenceActions.PARSE_PARAMS)
    protected parseParams: ParseParams,
    @inject(coreSequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
    @inject(coreSequenceActions.SEND) protected send: Send,
    @inject(coreSequenceActions.REJECT) protected reject: Reject,
    // We get the logger injected by the LogProvider here
    @inject(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

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.