Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rest): allow assigning express settings #2423

Merged
merged 1 commit into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/site/Server.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,25 @@ export async function main() {
For a complete list of CORS options, see
https://github.com/expressjs/cors#configuration-options.

### Express settings

Override the default express settings and/or assign your own settings:

```ts
const app = new RestApplication({
rest: {
expressSettings: {
'x-powered-by': false,
env: 'production',
...
},
},
});
```

Checkout `express` [documentation](http://expressjs.com/fr/api.html#app.set) for
more details about the build-in settings.

### Configure the Base Path

Sometime it's desirable to expose REST endpoints using a base path, such as
Expand Down
41 changes: 37 additions & 4 deletions packages/rest/src/__tests__/unit/rest.server/rest.server.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {anOperationSpec} from '@loopback/openapi-spec-builder';
import {Binding, Context} from '@loopback/context';
import {Application} from '@loopback/core';
import {RestServer, Route, RestBindings, RestComponent} from '../../..';
import {RequestBodyParserOptions} from '../../../types';
import {anOperationSpec} from '@loopback/openapi-spec-builder';
import {expect} from '@loopback/testlab';
import {
RequestBodyParserOptions,
RestBindings,
RestComponent,
RestServer,
RestServerConfig,
Route,
} from '../../..';

describe('RestServer', () => {
describe('"bindElement" binding', () => {
Expand Down Expand Up @@ -136,6 +142,33 @@ describe('RestServer', () => {
parserOptions,
);
});

it('assigns express settings', () => {
class TestRestServer extends RestServer {
constructor(application: Application, config: RestServerConfig) {
super(application, config);
this._setupRequestHandlerIfNeeded();
}

get expressApp() {
return this._expressApp;
}
}

const app = new Application();
const server = new TestRestServer(app, {
expressSettings: {
'x-powered-by': false,
env: 'production',
},
});
const expressApp = server.expressApp;
expect(expressApp.get('x-powered-by')).to.equal(false);
expect(expressApp.get('env')).to.equal('production');
// `extended` is the default setting by Express
expect(expressApp.get('query parser')).to.equal('extended');
expect(expressApp.get('not set')).to.equal(undefined);
});
});

async function givenRequestContext() {
Expand Down
14 changes: 13 additions & 1 deletion packages/rest/src/rest.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
protected _setupRequestHandlerIfNeeded() {
if (this._expressApp) return;
this._expressApp = express();
this._expressApp.set('query parser', 'extended');
this._applyExpressSettings();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I am reading these lines correctly, then:

  • before the change, we were explicitly configuring the Express instance to use extended query parser
  • now we use the default query parser configuration as provided by Express

I see that Express uses extended query parser by default, so I guess this is ok.

https://expressjs.com/en/4x/api.html#app.settings.table

this._requestHandler = this._expressApp;

// Allow CORS support for all endpoints so that users
Expand Down Expand Up @@ -245,6 +245,16 @@ export class RestServer extends Context implements Server, HttpServerLike {
);
}

/**
* Apply express settings.
*/
protected _applyExpressSettings() {
const settings = this.config.expressSettings || {};
for (const key in settings) {
this._expressApp.set(key, settings[key]);
}
}

/**
* Mount /openapi.json, /openapi.yaml for specs and /swagger-ui, /explorer
* to redirect to externally hosted API explorer
Expand Down Expand Up @@ -954,6 +964,8 @@ export interface RestServerOptions {
apiExplorer?: ApiExplorerOptions;
requestBodyParser?: RequestBodyParserOptions;
sequence?: Constructor<SequenceHandler>;
// tslint:disable-next-line:no-any
expressSettings?: {[name: string]: any};
ludohenin marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down