npm package: @juniorcitizen/express-web-server
Description: express web server implemented based on clean architecture
Author: juniorCitizen
Latest version: 0.0.1-alpha.13

# @juniorcitizen/express-web-server

> express web server implemented based on clean architecture

- [HIGHLIGHT](#highlight)

- [INSTALLATION](#installation)

- [USAGE](#usage)

- [PLUGINS AND EXTENSIONS](#plugins-and-extensions)

- [ROUTER PLUGIN SYSTEM](#router-plugin-system)

- [API](#api)

## HIGHLIGHTS

- Express.js web server written in typescript

- based on clean architecture

- popular Express.js middlewares are available as plug-ins

- accept external middleware plug-ins and server extensions

- plug-in routing system

## INSTALLATION

```bash
npm install --save @juniorcitizen/express-web-server
```

## USAGE

```js
import {
  StartWebServerUseCaseDriver as UseCaseDriver,
  StartWebServerServiceFactory as ServiceFactory,
  RouterPlugIn, // router plugin
  Morgan, // middleware plugins
} from '@juniorcitizen/express-web-server'

// factory for extending server functionalities
const serviceFactory = new ServiceFactory()

// add morgan logger plugin
const PROD_MODE = process.env.NODE_ENV==='production'
serviceFactory.plugIn(new Morgan({PROD_MODE: false}))

// add a router
const appRouter = new RouterPlugIn('/')
appRouter.addAllHandlers([middleware..., route handler...])

// add a second router
const testRouter = new RouterPlugIn('/test')
testRouter.addPostHandlers([middleware..., route handler...])

// attach testRouter to the appRouter
appRouter.attachChild(testRouter)

// attach appRouter to Express server
serviceFactory.plugIn(appRouter)

// instantiate server service
const startWebServer = new StartWebServer(serviceFactory)

// start server
startWebServer.execute({PORT: 3000})
```

## PLUGINS AND EXTENSIONS

### Available plugIns & extensions

- [**Response compression**](https://www.npmjs.com/package/compression)

- [**EJS templating engine**](https://www.npmjs.com/package/ejs)

- [**Server-side session with Redis caching**](https://www.npmjs.com/package/express-session):

  - redis client: [**ioredis**](https://www.npmjs.com/package/ioredis)

  - redis store: [**connect-redis**](https://www.npmjs.com/package/connect-redis)

- [**HTTP header security**](https://www.npmjs.com/package/helmet)

- [**JSON request-body parser**](https://expressjs.com/zh-tw/api.html#express.json)

- [**Request loggier**](https://www.npmjs.com/package/morgan)

- [**favicon caching**](https://www.npmjs.com/package/serve-favicon)

- [**static-file serving**](http://expressjs.com/en/starter/static-files.html#serving-static-files-in-express)

- [**trust proxy**](https://expressjs.com/en/guide/behind-proxies.html)

- [**urlencoded request-body parser**](https://expressjs.com/zh-tw/api.html#express.urlencoded)

- **TO DO**:

  - [**CSRF protection**](https://www.npmjs.com/package/csurf)

  - [**Enforce ssl**](https://www.npmjs.com/package/express-enforces-ssl)

  - [**HSTS protection**](https://www.npmjs.com/package/hsts)

  - [**Rate-limit**](https://www.npmjs.com/package/express-rate-limit)

  - [**Response throttling**](https://www.npmjs.com/package/express-slow-down)

  - [**XSS protection**](https://www.npmjs.com/package/x-xss-protection)

### How to roll your own plugIns & extensions

```js
import EnvironmentVariables from '@juniorcitizen/environment-variables'
import {
  StartWebServer,
  StartWebServerServiceFactory as ServiceFactory,
  AbstractServicePlugIn, // extend the plugin base class
} from '@juniorcitizen/express-web-server'

// example of a global route-middleware plugIn
class MyPlugIn extends AbstractServicePlugIn {
  // dependencies can be injected
  // through the constructor
  constructor(thing, someFunction) {
    super()
    this.thing = thing
    this.someFunction = someFunction
    this._middlware = (req, res, next) => {
      this.someFunction()
      console.log(this.thing)
      next()
    }
  }
  // expose the '_middleware' private member
  // useful if this middleware is used on particular routes (non-global)
  // ***implementation of this getter is required if writing typescript***
  // ***for global middlewares, just return undefined***
  getter middleware() {
    return this._middleware
  }
  // an instance of the Express app is exposed
  // to the 'execute' method, enable middleware
  // and extension to the Express server
  // ***implementation of this method is required***
  execute(app) {
    app.use(this._middleware)
  }
}

const serviceFactory = new ServiceFactory() // service factory
// make your plug-in dependencies
const someFunction = () => {
  console.log('someFunction is executed')
}
const thing = 'I am the thing'
const myPlugIn = new MyPlugIn(thing, someFunction) // instantiate your plug-in
serviceFactory.plugIn(myPlugIn) // register your plug-in
const startWebServer = new StartWebServer(serviceFactory) // instantiate server
// setup and plug-in your routers...
// ...
// ...
startWebServer.execute({PORT: 3000}) // start server
```

## ROUTER PLUGIN SYSTEM

to be completed... see the ['USAGE' section](#usage) for example

## API

to be completed... see the ['USAGE' section](#usage) for example