First, the necessary knowledge of server development

For front-end developers, the difficulty of learning Node development is not to learn a framework, nor to learn a language, but to systematically connect all things from the global server development.

What knowledge base is required for Node-server development?

In general, it is the language + framework + mysql + ORM framework. In fact, the learning cost is mainly language + framework.

Learning costs

The language is the foundation, can run demo point of view, at least a week or two, at most a month or two; It should take a week or two for the framework to get up and running and write a demo. Mysql only needs a day or two to know the basics. ORM framework also needs a day or two. (The time here is the minimum link running time, I advocate learning specific things in the scene in the case of link running)

Syntax + Framework

Server development, at least one language to learn, such as Node, Java, go and so on; After learning this language, you need to learn the corresponding framework of this language, such as the Egg framework for Node, such as the Spring framework for Java. The language learning is the grammar, and the framework uses this grammar to complete a certain function in a more efficient way.

The database

Learned framework, but also need to understand the knowledge of the database, because for the back-end students, need to deal with data, this is the place where we store data, we through interfaces, is that the data provided by the front end of the curd ability, selection without any special, with mysql, regardless of the size of the factory, basically use it, says from the learning cost, We spent a day or two learning how to build libraries and tables, and simply querying all the data, and then learning the details of specific business scenarios.

Database connection

After learning the database, there is another thing to learn, that is, database connection, Java database connection, the bottom provides JDBC scheme, node provides mysql package for database connection, it is equivalent to the development language and the bridge between the database, follow the general grammar rules, you can get started business development. However, this method is not friendly to use, because the front and back ends communicate through the way of objects, and we need to maintain the mapping relationship between database fields and objects, which is time-consuming and laborious. This is when the ORM framework was proposed.

ORM

ORM framework to solve the problem is the object and database mapping complex internal relationship, framework to solve, we only carry on simple use is good. The Java ORM framework is Mybatis, and egg provides such an ORM framework egg-sequelize.

Second, technical level

With that overall server-side development thinking in mind, it’s clear where egg is headed.

\

Egg is an enterprise-level framework based on Node that provides a complete set of capabilities for developing Node servers. The diagram below, on the left, shows some of the concrete entity objects involved in the framework, and on the right is the business layer of the Egg framework, which is kind of a conceptual thing. For details, you can read it through in conjunction with egg official documents.

\

1. Egg is a Node style MVC framework

It consists of several steps, the definition of a route, pointing to a controller; Controller is a controller that obtains parameters and returns data. Services handle specific business logic, such as database data retrieval, and so on.

  • Route definition: app/router.js
module.exports = app => { const { router, controller } = app; router.get('/', controller.home.index); // indicates that when a '/' is matched, it is directed to controller/home.js, where the class must have an index method. With this method, decide what to return.Copy the code
  • Controller is the controller
'use strict'; const Controller = require('egg').Controller; Class HomeController extends Controller {async index() {class HomeController extends Controller {async index() { This.ctx.request. Query (get), this.ctx.request. Body (post), this.ctx.request. Files (get file) const {CTX} = this; ctx.body = 'hi, egg'; // In general, this.ctx.body is the field returned by the server to the front. } } module.exports = HomeController;Copy the code
  • Service handles business logic
'use strict' const Service = require('egg').Service; // The service layer is the processing of the concrete business logic. In general, database data queries, logical judgments, and so on are performed. // Select * from the database where the current user exists. Exists abnormal returns' account of the existing class User extends the Service {async register (User) {const hasUser = await this. CTX. Model. The User. The findOne ({ where: { username: user.username } }); if (! hasUser) { const userInfo = await this.ctx.model.User.create(user); if (userInfo) { return this.ctx.response.ServerResponse.successRes(true) } return Enclosing CTX. Response. ServerResponse. ErrorRes (' abnormal user registration, true)} to return this. CTX. Response. ServerResponse. ErrorRes (' account already exists, true) } }Copy the code

2. Get the request parameters

  • Get gets request parameters: this.ctx.request.query
  • The post method gets the request parameter: this.ctx.request.body
  • File file: this.ctx.request.files

3. Extends extends

Helper for toolkit extension.

In front-end development, public functions are usually in an utils utility file.

In an Egg, the helper is used to extend the tool.

// app/extend/helper.js module.exports = { formatUser(user) { return only(user, [ 'name', 'phone' ]); }};Copy the code

At the time of use: this. CTX. Helper. FormatUser (obj).

Response, extended for the return response of the data request

In general, in this section, I’m going to restrict the return format of the data.

'use strict' // code code defines const SUCCESS = 0; const ERROR = 1; class MyResponseData { constructor(status, msg, data) { this.msg = msg; this.data = data; this.status = status; } static successRes(data) { return new MyResponseData(SUCCESS, 'success', data); } static errorRes(msg, data) { return new MyResponseData(ERROR, msg, data); {MSG: string, status: number, data: any} module.exports = { ServerResponse: MyResponseData }Copy the code

Other extends include Application, Request, Context, and so on.

4. Database

On the one hand, this is a technical barrier to the front-end itself, without understanding the back-end development of the front-end itself does not understand the database.

On the other hand, the demo that comes out of Egg doesn’t connect directly to the database, it’s just a working example. A lot of people break here.

If you want to run this part, you must have some concepts in your mind.

1. Generally speaking, we must have mysql installed on our own machine, and then remember the account and password of the installation, so that our local projects can connect to our database. The so-called database is the data storage system running on the machine, which is the tool provided by the database vendor.

2. In the online environment, our database is usually provided by a separate server. The technical term is RDS. Normally, all we need to worry about is the database account and password.

When you have mysql installed locally, you can configure it directly in egg.

config.sequelize = { dialect: 'mysql', // support: mysql, mariadb, postgres, mssql database: 'template-test',// database name host: '127.0.0.1', port: 3306, username: 'root', password: '*******',// own password delegate: 'model', baseDir: 'model', define: { // raw: true, underscored: true, freezeTableName: Timestamps: false, createdAt: "createdAt ", // Custom timestamp updatedAt: "UpdatedAt", // custom timestamp timezone: '+08:00' // save as local timezone}};Copy the code

\

5. How do I use Node to operate the database

This part has something to do with the ORM framework we choose

In our internal ORM framework, we chose egg-Sequelize.

Each ORM has its own set of syntax rules that can be manipulated directly through the relevant documentation.

This is the egg-sequelize model in which the individual defines a simple user. Egg-sequelize CURD all data in the database through the defined model.

// app/model/user.js
const crypto =require('crypto');

module.exports = app => {
    const {STRING, INTEGER, DATE} = app.Sequelize;

    const User = app.model.define('user', {
        id: {
            type: INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        username: STRING(30),
        password: {
            type: STRING(100),
            set: function(password) {
                // let pas = crypto.createHash('md5').update(password).digest('hex');
                let pas = crypto.createHash('md5').update(password).digest('hex');
                console.log('pas', pas)
                this.setDataValue("password", pas);
            },
            get: function() {
                return this.getDataValue('password');
            }
        },
        created_at: DATE,
        updated_at: DATE,
    })

    User.prototype.validPassword = function (psd) {
        console.log('psd', psd);
        console.log('this.password', this.password);
        let md5 = crypto.createHash('md5').update(psd).digest('hex')
        console.log('md5', md5);
        return this.password === crypto.createHash('md5').update(psd).digest('hex');
    }
    return User
}
Copy the code

Data query -findOne

const user = this.ctx.model.User.findOne({
  where: {
    username: user.username
  }
});
Copy the code

Data insertion -create

const userInfo = await this.ctx.model.User.create(user);
Copy the code

\

Data paging query -findAndCountAll

const userList = await this.ctx.model.User.findAndCountAll(query);
Copy the code

Query by ID -findByPk

const user = await this.ctx.model.User.findByPk(id);
Copy the code

Data update – Update

const user = await this.ctx.model.User.update(data,{where: {id}});
Copy the code

Third, business level

From the perspective of development, we have the basic technical ability, we found that as a front-end, the development of the service side will still have problems, these problems may be experience, or some of the conventional, but our front-end is relatively lacking.

For example, if we make a login, the password must be stored in ciphertext, how to encrypt it? What are the normal encryption methods? Therefore, I will also summarize some details that we need to know about development in view of these problems.

1, the crypto

A package provided by Node that performs algorithmic encryption (MD5, SHA1, etc.) and acts as ciphertext storage for passwords.

Why not plaintext storage? Prevent database data leakage and user account theft.

\

2, egg – sequelize

An ORM framework for egg framework, CURD of data.

Documents: eggjs.org/zh-cn/tutor…

3, JWT

JWT is a common user authentication solution that I won’t go into detail here.

Jsonwebtoken, a Node package for login authentication. The core has two apis.

// This is the signature, the generated token, which is returned to the front end. All subsequent interfaces are verified. You need to obtain the token in the header. Token = jwt.sign(data, key)Copy the code

4, the egg – validate

A tool for verifying parameters

Code sample

const query = this.ctx.request.body;
const params = {
  username: query.username,
  password: query.password
};
try {
  this.ctx.validate({
    username: 'string',
    password: 'string'
  }, params);
} catch(e) {
  this.ctx.body = e;
  return
}
Copy the code

Documents: www.npmjs.com/package/egg…

5, an egg – multipart

File upload plugin

Documents: github.com/eggjs/egg-m…

6. Multi-environment configuration

Generally, there are three environments: local, dev, and PROd

When started, the egg defaults to local. If you want to set the environment, you can set it on the command line. EGG_SERVER_ENV is a command line argument that specifies the runtime environment.

"Scripts ": {"start": "egg-scripts start --daemon --title=egg-server-template-node",// prod environment "stop": // local "dev:dev": // local "dev:dev": "EGG_SERVER_ENV=dev NPM run dev",// dev environment "debug": "egg-bin debug", "test": "npm run lint -- --fix && npm run test-local", "test-local": "egg-bin test", "cov": "egg-bin cov", "lint": "eslint .", "ci": "npm run lint && npm run cov", "autod": "autod" },Copy the code

You need to configure the config for different environments.

  • Config.default. js, the default environment is local.
  • Config.dev. js. This configuration will be used in the dev environment and will be merged with default.
  • Config.prod. js, prod configuration.

This piece of different configuration, in fact, in most cases, mainly different database configuration.

In general, the Egg official documentation can not completely solve the confusion of node server development for novices. This article is more of a supplement to the Egg official documentation to help novices start server development under the overall framework of thinking.

So that’s the end of egg.