Skip to content

Commit

Permalink
feat(rest): use @loopback/express-middleware to manage express middle…
Browse files Browse the repository at this point in the history
…ware
  • Loading branch information
raymondfeng committed Jun 12, 2019
1 parent 6c7af77 commit fe54778
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/rest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@loopback/http-server": "^1.4.0",
"@loopback/openapi-v3": "^1.6.1",
"@loopback/openapi-v3-types": "^1.1.1",
"@loopback/express-middleware": "^1.0.0-1",
"@types/body-parser": "^1.17.0",
"@types/cors": "^2.8.5",
"@types/express": "^4.17.0",
Expand Down
62 changes: 51 additions & 11 deletions packages/rest/src/rest.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
inject,
} from '@loopback/context';
import {Application, CoreBindings, Server} from '@loopback/core';
import {
ExpressBindings,
MiddlewareRegistry,
} from '@loopback/express-middleware';
import {HttpServer, HttpServerOptions} from '@loopback/http-server';
import {getControllerSpec} from '@loopback/openapi-v3';
import {
Expand Down Expand Up @@ -221,24 +225,50 @@ export class RestServer extends Context implements Server, HttpServerLike {
this._applyExpressSettings();
this._requestHandler = this._expressApp;

if (!this.isBound(ExpressBindings.EXPRESS_MIDDLEWARE_REGISTRY)) {
// Set up the default express middleware registry
this.bind(ExpressBindings.EXPRESS_MIDDLEWARE_REGISTRY).toClass(
MiddlewareRegistry,
);
}
const middlewareRegistry = this.getSync(
ExpressBindings.EXPRESS_MIDDLEWARE_REGISTRY,
);
middlewareRegistry.setMiddlewareRegistryOptions({
phasesByOrder: ['cors', 'openapi-spec', 'rest'],
});

// Allow CORS support for all endpoints so that users
// can test with online SwaggerUI instance
this._expressApp.use(cors(this.config.cors));
middlewareRegistry.middleware(cors(this.config.cors), {
phase: 'cors',
name: 'cors',
});

// Set up endpoints for OpenAPI spec/ui
this._setupOpenApiSpecEndpoints();
this._setupOpenApiSpecEndpoints(middlewareRegistry);

// Mount our router & request handler
this._expressApp.use(this._basePath, (req, res, next) => {
this._handleHttpRequest(req, res).catch(next);
});
middlewareRegistry.middleware(
(req, res, next) => {
this._handleHttpRequest(req, res).catch(next);
},
{
path: this._basePath,
phase: 'rest',
name: 'rest',
},
);

// Mount our error handler
this._expressApp.use(
middlewareRegistry.errorMiddleware(
(err: Error, req: Request, res: Response, next: Function) => {
this._onUnhandledError(req, res, err);
},
{name: 'error'},
);

this._expressApp.use(middlewareRegistry.requestHandler);
}

/**
Expand All @@ -258,7 +288,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
* Mount /openapi.json, /openapi.yaml for specs and /swagger-ui, /explorer
* to redirect to externally hosted API explorer
*/
protected _setupOpenApiSpecEndpoints() {
protected _setupOpenApiSpecEndpoints(middlewareRegistry: MiddlewareRegistry) {
if (this.config.openApiSpec.disabled) return;
// NOTE(bajtos) Regular routes are handled through Sequence.
// IMO, this built-in endpoint should not run through a Sequence,
Expand All @@ -270,14 +300,24 @@ export class RestServer extends Context implements Server, HttpServerLike {
const mapping = this.config.openApiSpec.endpointMapping!;
// Serving OpenAPI spec
for (const p in mapping) {
this._expressApp.get(p, (req, res) =>
this._serveOpenApiSpec(req, res, mapping[p]),
middlewareRegistry.middleware(
(req, res) => this._serveOpenApiSpec(req, res, mapping[p]),
{
path: p,
method: 'get',
phase: 'openapi-spec',
},
);
}

const explorerPaths = ['/swagger-ui', '/explorer'];
this._expressApp.get(explorerPaths, (req, res, next) =>
this._redirectToSwaggerUI(req, res, next),
middlewareRegistry.middleware(
(req, res, next) => this._redirectToSwaggerUI(req, res, next),
{
path: explorerPaths,
method: 'get',
phase: 'openapi-spec',
},
);
}

Expand Down

0 comments on commit fe54778

Please sign in to comment.