LoopBack4: доступ к хранилищу внутри перехватчика - PullRequest
0 голосов
/ 30 сентября 2019

Я хотел бы улучшить Interceptor в моем приложении LoopBack4, которое в настоящее время просто выводит мне начало и конец вызова метода контроллера в командной строке - как описано здесь: https://loopback.io/doc/en/lb4/Interceptors.html

Мой журнал-Интерцептор выглядит так:

export const Log: Interceptor = async (invocationCtx, next) => {
    // Wait until the interceptor/method chain returns
    const req = await invocationCtx.get(RestBindings.Http.REQUEST);

    try
    {
        const stackinfo = 'Class: ' + invocationCtx.targetClass.name + ' | Method: ' + invocationCtx.methodName + " | Request IPs: " + req.ips.concat(', ');

        logger.trace('Starting - ' + stackinfo);

        const result = await next();
        const res = await invocationCtx.get(RestBindings.Http.RESPONSE);

        logger.trace('Ending - ' + stackinfo + ' | Response Status Code: ' + res.statusCode);

        return result;
    }
    catch (e)
    {
        logger.error(e);
        throw e;
    }
};

Теперь я хотел бы улучшить этот Перехватчик, чтобы также регистрировать некоторые статистические данные в моем MySQL-Datasource. Моя проблема в том, как я могу получить доступ к хранилищу внутри перехватчика? Нужно ли вводить репозиторий, и если да, то как мне это сделать? Или есть лучший способ добиться этого?

1 Ответ

0 голосов
/ 30 сентября 2019

Я нашел решение самостоятельно:

  1. создать сервис:
export class StatisticService
{
    constructor(
        @repository(StatisticRecordRepository) public statisticsRepository: StatisticRecordRepository
    ) {}


    async increment(key: string, addend = 1): Promise<void>
    {
        const existing = await this.statisticsRepository.findOne({where: {StatsKey: key}});
        if(existing !== null)
        {
            // @ts-ignore
            existing.Counter = existing.Counter + addend;
            existing.UpdateTs = (new Date()).toISOString();
            await this.statisticsRepository.update(existing);
        }
        else
        {
            await this.statisticsRepository.create(new StatisticRecord({
                                                                           StatsKey: key,
                                                                           Counter:  addend
                                                                       }));
        }
    }
}


export const StatisticsServiceBindings = {
    VALUE: BindingKey.create<StatisticService>("services.StatisticsService")
};
привязать сервис в конструкторе приложений:
this.bind(StatisticsServiceBindings.VALUE).toClass(StatisticService);
получить и использовать Сервис в Log-Interceptor:
const stats = await invocationCtx.get(StatisticsServiceBindings.VALUE);
stats.increment(invocationCtx.targetClass.name + '::' + invocationCtx.methodName + ' [' + res.statusCode + ']');
...