Skip to content

Commit

Permalink
feat(example-todo): add morgan middleware if env var DEBUG is set
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondfeng committed May 5, 2020
1 parent b2df4e6 commit 4457495
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 4 deletions.
143 changes: 143 additions & 0 deletions examples/todo/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/todo/package.json
Expand Up @@ -45,6 +45,7 @@
"@loopback/rest-explorer": "^2.1.2",
"@loopback/service-proxy": "^2.1.2",
"loopback-connector-rest": "^3.6.0",
"morgan": "^1.10.0",
"tslib": "^1.11.1"
},
"devDependencies": {
Expand All @@ -56,6 +57,7 @@
"@types/node": "^10.17.21",
"@typescript-eslint/eslint-plugin": "^2.31.0",
"@typescript-eslint/parser": "^2.31.0",
"@types/morgan": "^1.9.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-plugin": "^2.2.1",
Expand Down
18 changes: 18 additions & 0 deletions examples/todo/src/__tests__/acceptance/todo.acceptance.ts
Expand Up @@ -11,6 +11,7 @@ import {
givenHttpServerConfig,
toJSON,
} from '@loopback/testlab';
import morgan from 'morgan';
import {TodoListApplication} from '../../application';
import {Todo} from '../../models/';
import {TodoRepository} from '../../repositories/';
Expand Down Expand Up @@ -184,6 +185,23 @@ describe('TodoApplication', () => {
});
});

context('allows logging to be reconfigured', () => {
it('logs http requests', async () => {
const logs: string[] = [];
const logToArray = (str: string) => {
logs.push(str);
};
app.configure<morgan.Options>('middleware.morgan').to({
stream: {
write: logToArray,
},
});
await client.get('/todos');
expect(logs.length).to.eql(1);
expect(logs[0]).to.match(/"GET \/todos HTTP\/1\.1" 200 - "-"/);
});
});

it('queries todos with a filter', async () => {
await givenTodoInstance({title: 'wake up', isComplete: true});

Expand Down
25 changes: 25 additions & 0 deletions examples/todo/src/application.ts
Expand Up @@ -9,6 +9,7 @@ import {RepositoryMixin} from '@loopback/repository';
import {RestApplication} from '@loopback/rest';
import {RestExplorerComponent} from '@loopback/rest-explorer';
import {ServiceMixin} from '@loopback/service-proxy';
import morgan from 'morgan';
import path from 'path';
import {MySequence} from './sequence';

Expand Down Expand Up @@ -36,5 +37,29 @@ export class TodoListApplication extends BootMixin(
nested: true,
},
};

this.setupLogging();
}

private setupLogging() {
// Register `morgan` express middleware
// Create a middleware factory wrapper for `morgan(format, options)`
const morganFactory = (config?: morgan.Options) => {
this.debug('Morgan configuration', config);
return morgan('combined', config);
};

// Print out logs using `debug`
const defaultConfig: morgan.Options = {
stream: {
write: str => {
this._debug(str);
},
},
};
this.expressMiddleware(morganFactory, defaultConfig, {
injectConfiguration: 'watch',
key: 'middleware.morgan',
});
}
}
16 changes: 12 additions & 4 deletions examples/todo/src/sequence.ts
Expand Up @@ -3,10 +3,11 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Context, inject} from '@loopback/context';
import {inject} from '@loopback/context';
import {
FindRoute,
InvokeMethod,
InvokeMiddleware,
ParseParams,
Reject,
RequestContext,
Expand All @@ -18,8 +19,14 @@ import {
const SequenceActions = RestBindings.SequenceActions;

export class MySequence implements SequenceHandler {
/**
* Optional invoker for registered middleware in a chain.
* To be injected via SequenceActions.INVOKE_MIDDLEWARE.
*/
@inject(SequenceActions.INVOKE_MIDDLEWARE, {optional: true})
protected invokeMiddleware: InvokeMiddleware = () => false;

constructor(
@inject(RestBindings.Http.CONTEXT) public ctx: Context,
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
@inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
@inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
Expand All @@ -30,12 +37,13 @@ export class MySequence implements SequenceHandler {
async handle(context: RequestContext) {
try {
const {request, response} = context;
await this.invokeMiddleware(context);
const route = this.findRoute(request);
const args = await this.parseParams(request, route);
const result = await this.invoke(route, args);
this.send(response, result);
} catch (error) {
this.reject(context, error);
} catch (err) {
this.reject(context, err);
}
}
}

0 comments on commit 4457495

Please sign in to comment.