Skip to content

Commit

Permalink
Add "app.api()" method for registering routes
Browse files Browse the repository at this point in the history
  • Loading branch information
bajtos committed Jun 30, 2017
1 parent 98770e5 commit 9cdce09
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
22 changes: 17 additions & 5 deletions packages/core/src/application.ts
Expand Up @@ -3,18 +3,15 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import * as assert from 'assert';
import {
Binding,
Context,
Constructor,
Provider,
inject,
} from '@loopback/context';
import {
OpenApiSpec,
Route,
ParsedRequest,
} from '.';
import {OpenApiSpec, Route, ParsedRequest, OperationObject} from '.';
import {ServerRequest, ServerResponse} from 'http';
import {Component, mountComponent} from './component';
import {getApiSpec} from './router/metadata';
Expand Down Expand Up @@ -139,6 +136,21 @@ export class Application extends Context {
return this.bind(`routes.${route.verb} ${route.path}`).to(route);
}

api(spec: OpenApiSpec) {
for (const path in spec.paths) {
for (const verb in spec.paths[path]) {
const routeSpec: OperationObject = spec.paths[path][verb];
const handler = routeSpec['x-operation'];
assert(
typeof handler === 'function',
`"x-operation" field of "${verb} ${path}" must be a function`);

const route = new Route(verb, path, routeSpec, handler);
this.route(route);
}
}
}

protected _logError(
err: Error,
statusCode: number,
Expand Down
19 changes: 19 additions & 0 deletions packages/core/test/acceptance/routing/routing.acceptance.ts
Expand Up @@ -221,6 +221,25 @@ describe('Routing', () => {
await client.get('/greet?name=world').expect(200, 'hello world');
});

it('supports routes declared via API specification', async () => {
const app = givenAnApplication();

function greet(name: string) {
return `hello ${name}`;
}

const spec = anOpenApiSpec()
.withOperation('get', '/greet', anOperationSpec()
.withParameter({name: 'name', in: 'query', type: 'string'})
.withExtension('x-operation', greet))
.build();

app.api(spec);

const client = await whenIMakeRequestTo(app);
await client.get('/greet?name=world').expect(200, 'hello world');
});

/* ===== HELPERS ===== */

function givenAnApplication() {
Expand Down
24 changes: 23 additions & 1 deletion packages/openapi-spec-builder/src/openapi-spec-builder.ts
Expand Up @@ -4,6 +4,7 @@
// License text available at https://opensource.org/licenses/MIT

import {
ExtensionValue,
OpenApiSpec,
OperationObject,
ResponseObject,
Expand Down Expand Up @@ -78,6 +79,17 @@ export class OpenApiSpecBuilder {
.withStringResponse(200));
}

/**
* Add a custom (extension) property to the operation definition.
*
* @param key The property name starting with "x-".
* @param value The property value.
*/
withExtension(key: string, value: ExtensionValue): this {
this._spec[key] = value;
return this;
}

/**
* Build the OpenApiSpec object.
*/
Expand Down Expand Up @@ -132,7 +144,17 @@ export class OperationSpecBuilder {
* @param name The name of the controller method implementing this operation.
*/
withOperationName(name: string): this {
this._spec['x-operation-name'] = name;
return this.withExtension('x-operation-name', name);
}

/**
* Add a custom (extension) property to the operation definition.
*
* @param key The property name starting with "x-".
* @param value The property value.
*/
withExtension(key: string, value: ExtensionValue): this {
this._spec[key] = value;
return this;
}

Expand Down

0 comments on commit 9cdce09

Please sign in to comment.