• Routing and subcontracting management
  • Monitor the Alinode or easy Monitory online
  • Connect to the Apollo configuration center
  • Lightweight event trigger egg-bus
  • Generic exception handler
  • Generic request logging

Routing and subcontracting management

The binding management of a route and controller in egg is configured as follows

// app/router.js
module.exports = app= > {
  const { router, controller } = app;
  router.get('/user/:id', controller.user.info);
};
Copy the code

There is a problem with the above methods. In the process of business promotion, the business is becoming more and more complex, so the unified management of routes will be messy. The best way is to use subcontracting management to manage in one’s own business domain.

${rootPath}/router.js

  const v1Router = router.namespace('/api/v1');
  const v1Controller = controller.v1;
  const v1RouterBasePath = path.resolve(__dirname, './routes/v1');
  
  const requireRouters = async (basePath, router, controller, middleware) => {
    const files = await fsPromises.readdir(basePath);
    files.forEach(file= > {
      require(path.join(basePath, file))(router, controller, middleware);
    });
  };

  requireRouters(v1RouterBasePath, v1Router, v1Controller, middleware);

Copy the code

Bind the controller and router files respectively by reading them.

Alinode is monitored online

alinode

Alinode has a few minor issues, not being debugged on Windows, and the whole environment is a bit of a hassle to install. Our online monitoring is still easy-Monitor

Online monitoring easy-monitor

Easy-monitor Usage Guide

Easy-monitor is relatively simple to deploy and Windows can debug.

Integrated Apollo distribution center

install

npm i egg-apollojs-no-schedule --save
Copy the code

plugins.js

exports.apollojs = {
  enable: true.package: 'egg-apollojs-no-schedule'};Copy the code

app/apollo/config.js

module.exports = {
  configServerUrl: <configServerUrl>, // Configure the center address
  appId: [appId], // appId
  clusterName: "default".namespaceName: 'application' // Do not write the namespace incorrectly. It needs to correspond to the configuration on Apollo
};
Copy the code

preload.js

require('egg-apollojs-no-schedule')
  .init(__dirname + '/config/apollo.js');
Copy the code

config.default.js

/ / loading process. The env
require('egg-apollojs-no-schedule').apollo.setEnv();
Copy the code

package.json

"scripts": {
    "start": "node preload.js && egg-scripts start --daemon --title=<application name> --port=<port>"
}
Copy the code

use

The following uses the online mongodb database connection address as an example

Value configured in Apollo

Mongoose. Url = "mongo: / / 127.0.0.1 / test"Copy the code

In config.default.js, use the configuration as

config.mongoose = {
    url: process.env['mongoose.url'].options: {
        useNewUrlParser: true.useCreateIndex: true.useUnifiedTopology: true.useFindAndModify: false.bufferMaxEntries: 0.poolSize: 1000,}};Copy the code

Lightweight event trigger egg- Bug

egg-bug

The installation

npm i egg-bus --save
Copy the code

use

exports.bus = {
  enable: true.package: 'egg-bus'};Copy the code

Configure config. Default. Js

// {app_root}/config/config.default.js
exports.bus = {
  debug: true.// Debug More logs are generated in this mode
  concurrency: 1./ / in the Bull queue handling concurrency: https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queueprocess
  listener: {
    ignore: null.// Ignore some files in the directory, https://eggjs.org/zh-cn/advanced/loader.html#ignore-string
    baseDir: 'listener'.options: { / / Bull Job configuration: https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queueadd
      attempts: 5.backoff: {
        delay: 3000.type: 'fixed',}}},job: {
    // The listener is the same, except that the default baseDir value is' job '
  },
  bull: { / / Bull queue configuration: https://github.com/OptimalBits/bull/blob/develop/REFERENCE.md#queue
    redis: {
      host: 'localhost'.port: 6379.db: 0,}},queue: {
    default: 'default'.// The default queue name
    prefix: 'bus'.// Queue prefix
  },
  queues: { // Configure it separately for different queues

    // For example, change the redis port for the default queue
    default: {
      redis: {
        port: 6380,},}},};Copy the code

Generic exception handler

/app/middleware/error_handler.js

'use strict';

module.exports = (option, app) = > {
  return async function (ctx, next) {
    try {
      await next();
    } catch (err) {
      // The details of the 500 error in production are not returned to the client because they may contain sensitive information
      let { code = 'Error', message = 'Error', status = 500 } = err;
      app.emit(status === 500 ? 'error' : 'warn', err, this);
      message = status === 500 && app.config.env === 'prod' ? 'Internal Server Error' : err.message;

      if (typeof code === 'number') {
        code = 'InternalError';
        message = 'The request processing has failed due to some unknown error, exception or failure.';
      }

      ctx.body = {
        code,
        message,
      };
      if (status === 422) { ctx.body.detail = err.errors; } ctx.status = status; }}; };Copy the code

Uniform error handling, with error details thrown if in the test environment and uniform errors thrown if in production.

Generic request logging

module.exports = () = > async (ctx, next) => {
  ctx.logger.info(`
  headers:The ${JSON.stringify({
    referer: ctx.headers.referer,
    token: ctx.headers.token,
    accessToken: ctx.headers.accesstoken,
    openId: ctx.headers.openid,
    devieId: ctx.headers.deviceid,
  })}
  body:The ${JSON.stringify(ctx.request.body)}
  `);
  await next();
  ctx.logger.info(`response: The ${JSON.stringify(ctx.response.body)}`);
};

Copy the code