Skip to content

Commit

Permalink
feat(rest): add openapi enhancer service
Browse files Browse the repository at this point in the history
add openapi spec enhancer to rest server

impl. loopbackio#4380

Signed-off-by: Douglas McConnachie <[email protected]>
  • Loading branch information
dougal83 committed Feb 24, 2020
1 parent 2123d9b commit f572622
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright IBM Corp. 2019. All Rights Reserved.
// Node module: @loopback/openapi-v3
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {bind} from '@loopback/core';
import debugModule from 'debug';
import {inspect} from 'util';
import {
asSpecEnhancer,
mergeOpenAPISpec,
OASEnhancer,
OpenApiSpec,
} from '../../../..';

const debug = debugModule('loopback:openapi:spec-enhancer');

/**
* A spec enhancer to add OpenAPI info spec
*/
@bind(asSpecEnhancer)
export class InfoSpecEnhancer implements OASEnhancer {
name = 'info';

modifySpec(spec: OpenApiSpec): OpenApiSpec {
const InfoPatchSpec = {
info: {title: 'LoopBack Test Application', version: '1.0.1'},
};
const mergedSpec = mergeOpenAPISpec(spec, InfoPatchSpec);
debug(`security spec extension, merged spec: ${inspect(mergedSpec)}`);
return mergedSpec;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {Application} from '@loopback/core';
import {Application, createBindingFromClass} from '@loopback/core';
import {anOpenApiSpec, anOperationSpec} from '@loopback/openapi-spec-builder';
import {get, post, requestBody} from '@loopback/openapi-v3';
import {model, property} from '@loopback/repository';
Expand All @@ -13,6 +13,7 @@ import {
RestComponent,
RestServer,
} from '../../..';
import {InfoSpecEnhancer} from './fixtures/info.spec.extension';

describe('RestServer.getApiSpec()', () => {
let app: Application;
Expand Down Expand Up @@ -311,6 +312,16 @@ describe('RestServer.getApiSpec()', () => {
});
});

it('invokes registered oas enhancers', async () => {
const EXPECTED_SPEC_INFO = {
title: 'LoopBack Test Application',
version: '1.0.1',
};
server.add(createBindingFromClass(InfoSpecEnhancer));
const spec = await server.getApiSpec();
expect(spec.info).to.eql(EXPECTED_SPEC_INFO);
});

async function givenApplication() {
app = new Application();
app.component(RestComponent);
Expand Down
23 changes: 23 additions & 0 deletions packages/rest/src/rest.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import {
BindingScope,
Constructor,
Context,
createBindingFromClass,
inject,
} from '@loopback/context';
import {Application, CoreBindings, Server} from '@loopback/core';
import {HttpServer, HttpServerOptions} from '@loopback/http-server';
import {
getControllerSpec,
OASEnhancerService,
OAS_ENHANCER_SERVICE,
OpenAPIObject,
OpenApiSpec,
OperationObject,
Expand Down Expand Up @@ -130,6 +133,12 @@ export class RestServer extends Context implements Server, HttpServerLike {
* @param res - The response.
*/

protected _OASEnhancer: OASEnhancerService;
public get OASEnhancer(): OASEnhancerService {
this._setupOASEnhancerIfNeeded();
return this._OASEnhancer;
}

protected _requestHandler: HttpRequestListener;
public get requestHandler(): HttpRequestListener {
if (this._requestHandler == null) {
Expand Down Expand Up @@ -219,6 +228,16 @@ export class RestServer extends Context implements Server, HttpServerLike {
this.bind(RestBindings.HANDLER).toDynamicValue(() => this.httpHandler);
}

protected _setupOASEnhancerIfNeeded() {
if (this._OASEnhancer != null) return;
this.add(
createBindingFromClass(OASEnhancerService, {
key: OAS_ENHANCER_SERVICE,
}),
);
this._OASEnhancer = this.getSync(OAS_ENHANCER_SERVICE);
}

protected _setupRequestHandlerIfNeeded() {
if (this._expressApp != null) return;
this._expressApp = express();
Expand Down Expand Up @@ -754,6 +773,10 @@ export class RestServer extends Context implements Server, HttpServerLike {
spec = this.updateSpecFromRequest(spec, requestContext);
}

// Apply OAS enhancers to the OpenAPI specification
this.OASEnhancer.spec = spec;
spec = await this.OASEnhancer.applyAllEnhancers();

return spec;
}

Expand Down

0 comments on commit f572622

Please sign in to comment.