# API Common

## Features

- Logger class that logs to console in dev mode and to File in non development mode
- Middlewares for
    - Request response logging
    - Error handler for uncaught exceptions, 400 bad request and explicitly set 500.
    - Correlation ID setting middleware
    - JWT unpacking
- Error Formatters
    ```javascript
    const Fmt =  require('api-common').Formatter;
    const err = new Error('Any error you want to log');
    const reporter = 'Place from which this log message is emitted';
    const appName = 'sample-app';
    Fmt.buildLogMessage(req, res, err, appName, reporter);
    ```
 - Ping and app info endpoints

## Steps

1. Install the package
    ```shell
    npm i api-common --save
    ```

2. Using the logger

    ```javascript
    'use strict';

    // Get the logger instance configured with provided config
    const logger = require('api-common').getLogger('fullPathToLogFile');

    // export it so that your rest of the application can simply consume
    // this preconfigured logger.
    module.exports = logger;
    ```

3. Using the middleware

    ```javascript
    'use strict';

    const SwaggerExpressMiddleware = require('swagger-express-mw');
    const SwaggerUIMiddleware = require('swagger-ui-middleware');

    // A very good middleware that works out of the box, please use it.
    const ResponseTimer = require('response-time');

    // STEP 1: Load the appconfig.json that has the logging config in it.
    const appConfig = require('./../config/appconfig.json');

    // STEP 2: Initialize the middleware
    const CustomMiddleware = require('api-common').Middleware.init(appConfig.appName);
    /*
      The app name can be provided any way you can.
    */

    const port = process.env.PORT || appConfig.port;
    const config = {
        appRoot: "./src" // required config
    };
    let app = require('express')();

    // STEP: 3 Start wiring up the middleware [Order is important]
    app.use(CustomMiddleware.CorrelationIdMiddleware);
    app.use(CustomMiddleware.RequestResponseMiddleware);
    app.use(ResponseTimer());

    SwaggerUIMiddleware.hostUI(app,{
        path: appConfig.swaggerUiPath,
        overrides: "./src/swagger"
    });

    SwaggerExpressMiddleware.create(config, function (err, swaggerExpress) {
        if (err) {
            throw err;
        }

        // install middleware
        swaggerExpress.register(app);

        // Wire error handlers after this line

        //STEP:4 ALWAYS put this middleware in the end. It ends request pipe.
        app.use(CustomMiddleware.ErrorLoggingMiddleware);
    });


    module.exports = app; // for testing

    app.listen(port);
    ```

4. Using the logger from within Sequelize model initializers

    ```javascript
    'use strict';
    const path = require('path');
    const dbconf = require('../../../config/dbconfig');
    // here we use the logger wrapper from #2
    const logger = require('../helpers/Logger');

    let Sequelize = require('sequelize');
    dbconf.CONNECTION_CONFIG.logging = function(sqlInfo){
        logger.debug({ sql: sqlInfo ,from: path.basename(__filename) });
    };
    ```

5. Using the ping and app info endpoints

    Pass in the express app and the configuration you want to show in the app info endpoint.

    ```javascript
    require('api-common').StatusInformation.initializeStatusEndpoints(app, { example: 'configuration' });
    ```

6. Important note when using within Swagger projects.
    - in `./config/default.yaml ` if it looks like
        ```yaml
        # pipe for all swagger-node controllers
            swagger_controllers:
              - onError: json_error_handler
              - cors
              - swagger_security
              - _swagger_validate
              - express_compatibility
              - _router
        ```

    - Make sure you remove the `onError` key. It interferes with our error handler.

        ```yaml
        # pipe for all swagger-node controllers
            swagger_controllers:
              - cors
              - swagger_security
              - _swagger_validate
              - express_compatibility
              - _router
        ```
