Skip to content

Commit

Permalink
Add .listening property
Browse files Browse the repository at this point in the history
  • Loading branch information
Hage Yaapa committed Jun 5, 2018
1 parent 6517a04 commit b3a7256
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 24 deletions.
45 changes: 44 additions & 1 deletion packages/http-server/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
# @loopback/http-server

This module implements the HTTP server endpoint for LoopBack 4 apps.
This package implements the HTTP / HTTPS server endpoint for LoopBack 4 apps.

## Overview

This is an internal package used by `RestServer` for creating its HTTP / HTTPS server.

## Installation

To use this package, you'll need to install `@loopback/http-server`.

```sh
npm i @loopback/htp-server
```

## Usage

`@loopback/http-server` should be instantiated with an instance of `RestServer`, HTTP / HTTPS options object, and a request handler function.

```js
import {RestServer} from '@loopback/rest';
import {Application} from '@loopback/core';

const app = new Application();
const restServer = new RestServer(app);
const httpServer = new HttpServer(restServer, {port: 3000, host: ''}, (req, res) => {});
```

Call the `start()` method to start the server.

```js
httpServer.start()
```

Call the `stop()` method to stop the server.

Use the `listening` property to check whether the server is listening for connections or not.

```js
if (httpServer.listening) {
console.log('Server is running');
} else {
console.log('Server is not running');
}
```

## Contributions

Expand Down
27 changes: 27 additions & 0 deletions packages/http-server/src/http-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,31 @@ import {RestServer, HttpRequestListener} from '@loopback/rest';
import {AddressInfo} from 'net';
import * as pEvent from 'p-event';

/**
* Object for specifyig the HTTP / HTTPS server options
*/
export type HttpOptions = {
port: number;
host: string | undefined;
};

/**
* HTTP / HTTPS server used by LoopBack's RestServer
*
* @export
* @class HttpServer
*/
export class HttpServer {
private restServer: RestServer;
private httpPort: number;
private httpHost: string | undefined;
private httpServer: Server;

/**
* @param restServer
* @param httpOptions
* @param httpRequestListener
*/
constructor(
restServer: RestServer,
httpOptions: HttpOptions,
Expand All @@ -30,6 +44,9 @@ export class HttpServer {
this.httpServer = createServer(httpRequestListener);
}

/**
* Starts the HTTP / HTTPS server
*/
public start(): Promise<void> {
this.httpServer.listen(this.httpPort, this.httpHost);
return new Promise<void>(async (resolve, reject) => {
Expand All @@ -44,6 +61,9 @@ export class HttpServer {
});
}

/**
* Stops the HTTP / HTTPS server
*/
public stop(): Promise<void> {
this.httpServer.close();
return new Promise<void>(async (resolve, reject) => {
Expand All @@ -55,4 +75,11 @@ export class HttpServer {
}
});
}

/**
* Whether the HTTP / HTTPS server is listening or not
*/
public get listening(): Boolean {
return this.httpServer.listening;
}
}
30 changes: 23 additions & 7 deletions packages/http-server/test/integration/http-server.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@
// Node module: @loopback/http-server
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import {HttpServer} from '../..';
import {RestServer, RestComponent} from '@loopback/rest';
import {Application, ApplicationConfig} from '@loopback/core';
import * as assert from 'assert';

describe('http-server', () => {
// it('creates an instance of HTTP server', async () => {
// const httpServer: HttpServer = new HttpServer();
// });
// it('starts the HTTP server', async () => {});
// it('stops the HTTP server', async () => {});
describe('HttpServer', () => {
it('starts server', async () => {
const server = await givenAServer();
await server.start();
assert(server.listening, 'Server not started');
await server.stop();
});

it('stops server', async () => {
const server = await givenAServer();
await server.start();
await server.stop();
assert(!server.listening, 'Server not stopped');
});

async function givenAServer(options?: ApplicationConfig) {
const app = new Application(options);
app.component(RestComponent);
return await app.getServer(RestServer);
}
});
37 changes: 22 additions & 15 deletions packages/http-server/test/unit/http-server.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import {HttpServer} from '../..';
import {RestServer, RestComponent, RestBindings} from '@loopback/rest';
import {Application, ApplicationConfig} from '@loopback/core';
import {expect, createClientForHandler} from '@loopback/testlab';
import {RestServer} from '@loopback/rest';
import {Application} from '@loopback/core';
import * as assert from 'assert';

describe('HttpServer', () => {
// it('updates rest.port binding when listening on ephemeral port', async () => {
// const server = await givenAServer();
// await server.start();
// expect(server.getSync(RestBindings.PORT)).to.be.above(0);
// await server.stop();
// });
// it('stops the HTTP server', async () => {});
// async function givenAServer(options?: ApplicationConfig) {
// const app = new Application(options);
// app.component(RestComponent);
// return await app.getServer(RestServer);
// }
it('starts server', async () => {
const server = await givenAServer();
await server.start();
assert(server.listening, 'Server not started');
await server.stop();
});

it('stops server', async () => {
const server = await givenAServer();
await server.start();
await server.stop();
assert(!server.listening, 'Server not stopped');
});

async function givenAServer() {
const app = new Application();
const restServer = new RestServer(app);
return new HttpServer(restServer, {port: 3000, host: ''}, (req, res) => {});
}
});
12 changes: 11 additions & 1 deletion packages/rest/src/rest.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class RestServer extends Context implements Server, HttpServerLike {
this._setupHandlerIfNeeded();
return this._httpHandler;
}
protected _httpServer: Server;
protected _httpServer: HttpServer;

protected _expressApp: express.Application;

Expand Down Expand Up @@ -594,6 +594,16 @@ export class RestServer extends Context implements Server, HttpServerLike {
return this._httpServer.stop();
}

/**
* Whether the REST server is listening or not
*
* @returns {Boolean}
* @memberof RestServer
*/
public get listening(): Boolean {
return this._httpServer.listening;
}

protected _onUnhandledError(req: Request, res: Response, err: Error) {
if (!res.headersSent) {
res.statusCode = 500;
Expand Down

0 comments on commit b3a7256

Please sign in to comment.