preface

In the previous part, we have introduced the modules of project process design, database construction, JWT login and so on.

In this article we introduce branch management design and other basic modules.

The backend module

  1. DevOps – Gitlab Api usage (completed, click to jump)
  2. DevOps – Build DevOps base platform (50% completed) Click to jump to the base platform
  3. DevOps – Gitlab CI pipeline construction
  4. Devops-jenkins pipelined construction
  5. Devops-docker use
  6. DevOps – Release task flow design
  7. DevOps – Code review points
  8. Devops-node monitors service quality

The above series may be adjusted later based on the actual development progress of the DevOps project

Git branch management process

Git Flow process

Production branch

This branch can only be merged from other branches and cannot be modified directly in this branch

Develop branch

This branch is the main development branch and contains all the code to be released to the next Release. This branch is mainly merged with other branches, such as the Feature branch

Feature branch

This branch is primarily used to Develop a new feature, and once that’s done, we merge back into the Develop branch and go to the next Release

The Release branch

When a new Release needs to be released, a Release branch is created based on the Develop branch and merged into the Master and Develop branches once the Release is complete

Hotfix branch

When Production discovers a new Bu G, a Hotfix needs to be created. After the Hotfix is completed, it is merged back into the Master and Develop branches, so changes to the Hotfix go to the next Release

The overall branch management process is shown in the figure below

Project self-built process

The above Git Flow process can standardize and constrain the development quality and process. Let’s modify part of the process slightly and integrate it into the project.

As shown in the figure, each project shares a version number. Branch creation can be divided into three modes: version upgrade, feature update, and patch revision. The naming rules for all branches of the project will be upgraded without repetition and degradation.

Advantages of the above process:

  1. The project is locked with a fixed version. The version corresponds to the demand process and the quality of on-line is guaranteed
  2. Each development branch can only be deployed to the test environment and must be merged into the corresponding version branch before it can go into production
  3. All branches merged into master or Relase will be deleted to prevent one branch from processing too many services, making it difficult to review and roll back later
  4. After the realSE version branch is online, the corresponding tag is generated
  5. The hotfix version can be pulled out from the corresponding tag, and you can clearly know which version of the hotfix problem is fixed

Disadvantages of the above process:

  1. The version creation rule is fixed, and the version cannot be upgraded but can only be degraded
  2. Process constraints reduce development flexibility

There is no perfect solution, all Devops processes need to be designed according to the needs of real projects. The above is just one solution, please add my wechat Cookieboty for more general solution design

DevOps Development Chapter

Add global error callback

There is no absolutely safe program, all programs in the run due to various circumstances will appear error, global error callback is necessary for the base module.

export default class HttpExceptions extends Error { // Inherit to modify the error type
  code: number;
  msg: string;
  httpCode: number;

  constructor({ msg = "Server exception", code = 1, httpCode = 400 }) {
    super(a);this.msg = msg;
    this.code = code;
    this.httpCode = httpCode; }}import HttpExceptions from ".. /exceptions/http_exceptions"; // Global intercept error handling

export default() = > {return async function errorHandler(ctx, next) {
    try {
      await next();
    } catch (err) {
      // All exceptions raise an error event on the app, and the framework logs an error
      ctx.app.emit("error", err, ctx);

      let status = err.status || 500;
      let error: any = {};

      if (err instanceof HttpExceptions) {
        status = err.httpCode;
        error.requestUrl = `${ctx.method} : ${ctx.path}`;
        error.msg = err.msg;
        error.code = err.code;
        error.httpCode = err.httpCode;
      } else {
        // Unknown exception, system exception, no stack information displayed online
        // The details of the 500 error in production are not returned to the client because they may contain sensitive information
        error.code = 500;
        error.errsInfo =
          status === 500 && ctx.app.config.env === "prod"
            ? "Internal Server Error"
            : err.message;
      }
      // Read each property from the error object and set it into the response
      ctx.body = error;
      if (status === 422) { ctx.body.detail = err.errors; } ctx.status = status; }}; };Copy the code

As mentioned above, we expand the default error class and add error middleware to intercept global exceptions. If a custom exception is thrown, the global exception will be processed; otherwise, 500 errors will be thrown to remove sensitive information.

Use the webSocket

Why use webSocket

In project management, it will involve multi-person cooperative operation of the same project, and Ajax rotation training not only consumes performance, but also cannot fully guarantee real-time performance, and will push a lot of invalid information. Therefore, the project adopts Websocket to push the information of multi-person collaboration and the status push of the later construction process.

egg-socket

The framework provides the egg-socket. IO plug-in, which adds the following development specifications:

  • Namespace: Define a namespace (namespace) by configuration.
  • Middleware: Preprocesses every socket connection setup/disconnect, and every message/data transfer
  • Controller: indicates the event that responds to socket. IO
  • Router: unified socket. IO event and frame route processing configuration.

For details, see egg-socket. IO. The following is a brief description of ts configuration

import { Application } from "egg"; // Indicates the IO route usage
import { EggShell } from "egg-shell-decorators";

export default (app: Application) => {
  const { router, controller, io } = app;

  EggShell(app);

  // socket.io
  io.of('/').route('server', io.controller.nsp.ping);
};
Copy the code

The IO. Controller. NSP report type is undefined in ts usage, so you need to modify the typings/index.d.ts file.

import "egg";

declare module "egg" {
  interface Application { }
  interface CustomController {
    nsp: any;
  }

  interface EggSocketNameSpace {
    emit: any
  }
}
Copy the code

socket.io-client

window.onload = function () {
  // init
  const socket = io('http://127.0.0.1:7001', {
    // In practice, you can pass arguments here
    query: {
      room: 'nsp'.userId: `client_The ${Math.random()}`,},transports: ['websocket']}); socket.on('connect'.() = > {
    const id = socket.id;

    log('#connect,', id, socket);

    // Listen to your own ID for p2p communication
    socket.on(id, (msg: any) = > {
      log('#receive,', msg);
    });
  });

  // Receive online user information
  socket.on('online'.(msg: any) = > {
    log('#online,', msg);
  });

  // System events
  socket.on('disconnect'.(msg: any) = > {
    log('#disconnect', msg);
  });

  socket.on('disconnecting'.() = > {
    log('#disconnecting');
  });

  socket.on('error'.() = > {
    log('#error');
  });

  window.socket = socket;
};
Copy the code

The client uses socket. IO -client to connect to websocket. The above is the basic link part, the specific implementation should be developed according to the business requirements.

Customer side implementation

In order to ensure the speed of project development, the client chooses ANT DESIGN PRO. Please refer to the tutorial for specific installation steps. Here we show part of the business side code.

JWT front-end use

/** * exception handler */
const errorHandler = (error: { response: Response }): Response= > {
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;

    if (response.status === 401) {
      window.location.href = '/user/login';
    }
    notification.error({
      message: 'Request error${status}: ${url}`.description: errorText,
    });
  } else if(! response) { notification.error({description: 'Your network is abnormal and you cannot connect to the server'.message: 'Network exception'}); }return response;
};

/** * Configures the default parameter */ for the request
const request = extend({
  prefix: '/api',
  errorHandler, // Default error handling
  credentials: 'include'.// Whether cookies are included in the request by default
  headers: {
    authorization: localStorage.getItem('authorization'), // Read the locally saved authorization token}});export default request;
Copy the code

Modify the Request module

import request from '@/utils/request';

export interface LoginParamsType {
  username: string;
  password: string;
  mobile: string;
  captcha: string;
}

export async function fakeAccountLogin(params: LoginParamsType) {
  return request('/user/getUserToken', {
    getResponse: true.// Enable the return header parameter to save the corresponding authorization token for local use
    method: 'POST'.data: { params },
  });
}
Copy the code

As shown above, if you get the token in the Response header, you can request the interface normally.

The end of the

This project is from zero development, the subsequent series of blog will be launched according to the actual development progress (really f * * king tired), after the completion of the project, will open part of the source code for your reference.

If you have any questions or opinions about the content of the article, please add the wechat Cookieboty communication.

Also follow the public account Cookieboty1024, welcome to join the front end soldier growth camp