Skip to content

Commit

Permalink
feat(rest): allow basePath for rest servers
Browse files Browse the repository at this point in the history
See #918
  • Loading branch information
raymondfeng committed Dec 3, 2018
1 parent cb57a42 commit 9d55526
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
23 changes: 21 additions & 2 deletions packages/rest/src/rest.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
public requestHandler: HttpRequestListener;

public readonly config: RestServerConfig;
private _basePath: string;
protected _httpHandler: HttpHandler;
protected get httpHandler(): HttpHandler {
this._setupHandlerIfNeeded();
Expand Down Expand Up @@ -186,6 +187,12 @@ export class RestServer extends Context implements Server, HttpServerLike {
this.sequence(config.sequence);
}

let basePath = config.basePath || '';
// Trim leading and trailing `/`
basePath = basePath.replace(/(^\/)|(\/$)/, '');
if (basePath) basePath = '/' + basePath;
this._basePath = basePath;

this._setupRequestHandler();

this.bind(RestBindings.HANDLER).toDynamicValue(() => this.httpHandler);
Expand Down Expand Up @@ -220,7 +227,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
this._setupOpenApiSpecEndpoints();

// Mount our router & request handler
this._expressApp.use((req, res, next) => {
this._expressApp.use(this._basePath, (req, res, next) => {
this._handleHttpRequest(req, res).catch(next);
});

Expand Down Expand Up @@ -374,6 +381,14 @@ export class RestServer extends Context implements Server, HttpServerLike {
specObj.servers = [{url: this._getUrlForClient(request)}];
}

if (specObj.servers && this._basePath) {
for (const s of specObj.servers) {
if (s.url.startsWith('/')) {
s.url = s.url === '/' ? this._basePath : this._basePath + s.url;
}
}
}

if (specForm.format === 'json') {
const spec = JSON.stringify(specObj, null, 2);
response.setHeader('content-type', 'application/json; charset=utf-8');
Expand Down Expand Up @@ -442,7 +457,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
// add port number of present
host += port !== '' ? ':' + port : '';

return protocol + '://' + host;
return protocol + '://' + host + this._basePath;
}

private async _redirectToSwaggerUI(
Expand Down Expand Up @@ -884,6 +899,10 @@ export interface ApiExplorerOptions {
* Options for RestServer configuration
*/
export interface RestServerOptions {
/**
* Base path for API/static routes
*/
basePath?: string;
cors?: cors.CorsOptions;
openApiSpec?: OpenApiSpecOptions;
apiExplorer?: ApiExplorerOptions;
Expand Down
33 changes: 33 additions & 0 deletions packages/rest/test/integration/rest.server.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,39 @@ paths:
await server.stop();
});

it('allows `basePath` for routes', async () => {
const root = ASSETS;
const server = await givenAServer({
rest: {
basePath: '/api',
port: 0,
},
});
server.static('/html', root);
server.controller(DummyController);

const content = fs
.readFileSync(path.join(root, 'index.html'))
.toString('utf-8');
await createClientForHandler(server.requestHandler)
.get('/api/html/index.html')
.expect('Content-Type', /text\/html/)
.expect(200, content);

await createClientForHandler(server.requestHandler)
.get('/api/html')
.expect(200, 'Hi');

await createClientForHandler(server.requestHandler)
.get('/html')
.expect(404);

const response = await createClientForHandler(server.requestHandler).get(
'/openapi.json',
);
expect(response.body.servers).to.containEql({url: '/api'});
});

async function givenAServer(options?: {rest: RestServerConfig}) {
const app = new Application(options);
app.component(RestComponent);
Expand Down

0 comments on commit 9d55526

Please sign in to comment.