Skip to content
This repository has been archived by the owner on Feb 2, 2018. It is now read-only.

Commit

Permalink
Implement a basic decorator
Browse files Browse the repository at this point in the history
Implement a `@txIdFromHeader()` decorator that can annotate a
controller operation to receive the value of `X-Trasaction-Id` Header.
  • Loading branch information
virkt25 committed Sep 27, 2017
1 parent cf56cd4 commit 49ae6f7
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 1 deletion.
6 changes: 6 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright IBM Corp. 2013,2017. All Rights Reserved.
// Node module: loopback-next-extension-starter
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

export * from './src';
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"lint": "tslint -c tslint.full.json --project tsconfig.json --type-check",
"lint:fix": "npm run lint -- --fix",
"prepublish": "npm run build",
"pretest": "npm run build",
"clean": "rm -rf dist dist6",
"pretest": "npm run clean && npm run build",
"test": "mocha",
"posttest": "npm run lint",
"vscode-test": "mocha && npm run lint"
Expand Down
46 changes: 46 additions & 0 deletions src/decorators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Decorators

## Overview

Decorators provide annotations for class methods and properties. Decorators use the form `@decorator` where `decorator` is the name of the function that will be called at runtime.

## Basic Usage

### txIdFromHeader

This simple decorator allows you to annotate a Controller operation. The decorator will annotate the operation with the value of the header `X-Transaction-Id` from the request.

**Example**
```
class MyController {
@get('/')
@txIdFromHeader()
getHandler(txId: string) {
return `Your transaction id is: ${txId}`;
}
}
```

## Related Resources

You can check out the following resource to learn more about decorators and how they are used in LoopBack Next.

- [TypeScript Handbook: Decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)
- [Decorators in LoopBack](http://loopback.io/doc/en/lb4/Decorators.html)

## Contributions

- [Guidelines](http://loopback.io/doc/en/contrib/index.html)
- [Join the team](https://github.com/strongloop/loopback-next/issues/110)

## Tests

Run `npm test` from the root folder.

## Contributors

See [all contributors](https://github.com/strongloop/loopback-next-extension-starter/graphs/contributors).

## License

MIT
14 changes: 14 additions & 0 deletions src/decorators/txIdFromHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-next-extension-starter
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {param} from '@loopback/core';

/**
* Decorator to inject the current transaction-id from a request's
* 'X-Transaction-Id' header into the decorated function.
*/
export function txIdFromHeader() {
return param.header.string('X-Transaction-Id');
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
// Node module: loopback-next-extension-starter
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

export * from './decorators/txIdFromHeader';
46 changes: 46 additions & 0 deletions test/acceptance/txIdFromHeader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: @loopback/core
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Application, get} from '@loopback/core';
import {txIdFromHeader} from '../..';
import {Client, createClientForApp} from '@loopback/testlab';

describe('@txIdFromHeader() tests', () => {
let app: Application;

beforeEach(createApp);
beforeEach(createController);

it('works with header set', async () => {
const client: Client = createClientForApp(app);

await client
.get('/')
.set('X-Transaction-Id', 'testid123')
.expect(200, 'Your id is testid123');
});

it('works without header', async () => {
const client: Client = createClientForApp(app);

await client.get('/').expect(200, 'Your id is undefined');
});

function createApp() {
app = new Application();
}

function createController() {
class MyController {
@get('/')
@txIdFromHeader()
test(txId: string) {
return `Your id is ${txId}`;
}
}

app.controller(MyController);
}
});
28 changes: 28 additions & 0 deletions test/unit/txIdFromHeader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: @loopback/core
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {get, getControllerSpec} from '@loopback/core';
import {txIdFromHeader} from '../..';

describe('@txHeaderFromId', () => {
it('defines a parameter for X-Transaction-Id', () => {
class MyController {
@get('/')
@txIdFromHeader()
hello(txId: string) {}
}

const actualSpec = getControllerSpec(MyController);

expect(actualSpec.paths['/']['get'].parameters).to.eql([
{
name: 'X-Transaction-Id',
type: 'string',
in: 'header',
},
]);
});
});

0 comments on commit 49ae6f7

Please sign in to comment.