express in node.js

Keywords: node.js

Introduction to express

Express is a third-party module used to quickly build the server (instead of http module)  

Express is a fast, open and minimalist web development framework based on Node.js platform.

Express retains the basic API of http module. When using express, you can also use http API

express also encapsulates some new methods to make it easier for us to build the server

Express provides middleware functions, and many other powerful third-party modules are developed based on express

Install express

In the project folder, execute npm i express. You can download and install express.  

Note: Express cannot be installed in the express folder. Otherwise, the installation fails.

Constructing a Web server using Express

Steps:  

1. Load the express module

2. Create an express server

3. Turn on the server

4. Listen for browser requests and process them

// Building a web server using express
// 1) Load express module
const express = require('express');

// 2) Create an express server
const app = express();

// 3) Turn on the server
app.listen(3006, () => console.log('express The server is working'));

// 4) Listen for browser requests and process them

app.get('GET Requested address', Processing function);

app.post('POST Requested address', Processing function);

The reason why express can build a web server is that it encapsulates the core module http.

After encapsulation, express provides a very convenient and easy-to-use method.

For example, app.get() and app.post() are the new methods of express encapsulation.

Here is another res.send() method

This method can replace the previous res.end method and is better than res.end method

  res.send() is used to respond

  The content of the response cannot be numeric

  If the response is a JS object, the method will automatically convert the object to JSON format.

  And the content type response header will be added automatically

  If you have responded, don't respond again.

const express = require('express');
const app = express();
app.listen(3006, () => console.log('It's on'));

// Write interface
app.get('/api/test', (req, res) => {
  // res.end('hello world, ha ha ')// The response Chinese will be garbled. You must add your own response header
  res.end(JSON.stringify({ status: 0, message: 'login was successful' })); // Only response string or buffer type can be used

  // The send method provided by express can solve the above two problems
  res.send({ status: 0, message: 'login was successful' }); // The send method will automatically set the response header; And it will automatically convert the object to JSON string
});

Note that in express, we can still use the methods and properties in the http module, such as req.url.

Express routing

Routing: the mapping relationship between request and handler.

  Benefits of using routing

Reduce matching times and improve performance

Classified management interface, easier to maintain and upgrade

login.js

// ---------------------To use routing----------------------
// 1. Load express
const express = require('express');
// 2. Creating a routing object is actually a function type
const router = express.Router();

// 3. Write the interface and mount the interface to the router
router.post('/reguser', (req, res) => {});
router.post('/login', (req, res) => {});

// Be sure to export router
module.exports = router;

index.js

// Three lines of required code to start the service
const express = require('express');
const app = express();

// Load the customized routing module and register the middleware
let loginRouter = require('./routers/login');
app.use('/api', loginRouter);

app.listen(3006, () => console.log('It's on'));

Express Middleware

  Middleware, especially the intermediate processing link of business process.

Middleware is not only the biggest feature of express, but also the most important design

Many third-party modules can be used as express middleware to make development easier with express.

An express application is completed by a variety of middleware combinations

Middleware is essentially a function

Middleware principle

Several forms of Middleware

// The following middleware only serves the current interface / my/userinfo
app.get('/my/userinfo', Middleware function);

// The following middleware handles the / api/login interface
app.post('/api/login', Middleware function, Middleware function, Middleware function, Middleware function .....);

// The middleware in app.use can handle all GET requests and all POST requests. If no path is specified, it can handle all interfaces
app.use(Middleware function);

// The following middleware functions only handle the interfaces beginning with / api
app.use('/api', Middleware function);

// The following middleware functions handle the / abcd and / abd interfaces
app.use('/abc?d', Middleware function);

Middleware syntax

Middleware is a function

There are four basic parameters in the middleware function, err, req, res and next

Middleware classification

Application level middleware (Middleware in index.js, globally valid)

Routing level middleware (the middleware in the routing file is only valid in the current routing file)

Error handling middleware (all four parameters need to be filled in, usually put at the end)

Built in middleware (built in express, such as express.urlencoded ({extended: true}))

Third party middleware (such as multer, express JWT, express session,...)

Set ignore file (. gitignore)

# Only nodes in the root directory are ignored_ modules
/node_modules

# Ignore all nodes_ Modules folder
node_modules/

# Ignore all. a files
*.a

# But track all lib.a, even if you ignored the. a file earlier
!lib.a

# Only TODO files in the current directory are ignored, not subdir/TODO
/TODO

# Ignore the folder named build in any directory
build/

# Ignore doc/notes.txt, but do not ignore doc/server/arch.txt
doc/*.txt

# Ignore. pdf files in the doc / directory and all its subdirectories
doc/**/*.pdf

Verify that the user name exists

Query according to the user name to see whether the data can be found.

// Complete interface project
// The first three lines start the service
const express = require('express');
const app = express();
app.listen(3006, () => console.log('It's on'));

// Configuration + write interface

app.use(urlencoded({ extended: true }));

// --------------------Register interface----------------------
// Request body: username password
app.post('/api/reguser', (req, res) => {
  // 1. The interface shall receive data
  console.log(req.body); // { username: 'laotang', password: '123456' }
  let { username, password } = req.body;
  // 2. Judge whether the account has been occupied
  db('select * from user where username="${username}"', (err, result) => {
    if (err) throw err;
    // console.log(result); //  Information is found, and result is a non empty array; No information found. Result is an empty array
    if (result.length > 0) {
      res.send({ status: 1, message: 'The user name is occupied' });
    } else {
      // Not occupied
      // 3. If it is not occupied, add the account and password to the database
      
    }
  })
});

Complete registration

// --------------------Register interface----------------------
// Request body: username password
app.post('/api/reguser', (req, res) => {
  // 1. The interface shall receive data
  // console.log(req.body); // { username: 'laotang', password: '123456' }
  let { username, password } = req.body;
  // 2. Judge whether the account has been occupied
  db(`select * from user where username='${username}'`, (err, result) => {
    if (err) throw err;
    // console.log(result); //  Information is found, and result is a non empty array; No information found. Result is an empty array
    if (result.length > 0) {
      res.send({ status: 1, message: 'The user name is occupied' });
    } else {
      // Not occupied
      // 3. If it is not occupied, add the account and password to the database
      db(`insert into user set username='${username}', password='${password}'`, (e, r) => {
        if (e) throw e;
        res.send({ status: 0, message: 'login was successful' });
      });
    }
  });
});

md5 encrypt password

The commonly used encryption method is md5.

Download and install the third-party encryption module and deconstruct the md5 method inside

let { md5 } = require('utility')

  Encrypt password

password = md5(password)

Complete login interface

/**
 * Login interface
 * Request method: POST
 * Interface address: / api/login
 * Request body: username | password
 */
app.post('/api/login', (req, res) => {
  // console.log(req.body); // { username: 'laotang', password: '123456' }
  let { username, password } = req.body;
  password = md5(password);
  // Use username and encrypted password as conditions to query.
  let sql = `select * from user where username='${username}' and password='${password}'`;
  db(sql, (err, result) => {
    if (err) throw err;
    // console.log(result); //  No result is found and an empty array is obtained; The result is a non empty array
    if (result.length > 0) {
      res.send({ status: 0, message: 'Login succeeded' })
    } else {
      res.send({ status: 1, message: 'Wrong account or password' })
    }
  })
});

Create token

Create a token string using the third-party module jsonwebtoken.

Download and install npm i jsonwebtoken

Load module const jwt = require('jsonwebtoken ');

if (result.length > 0) {
  // Login succeeded and a token is generated
  // Save the user's id in the token
  // "Bearer" must be added before the token. Pay attention to the space
  let token = 'Bearer ' + jwt.sign({ id: result[0].id }, 'sfsws23s', { expiresIn: '2h' });
  res.send({ status: 0, message: 'Login succeeded', token })
} else {
  res.send({ status: 1, message: 'Wrong account or password' })
}

Verification Middleware

// The middleware must be registered here to complete the data verification
router.use((req, res, next) => {
  // Get username and password
  let { username, password } = req.body;
  // Verify user name
  if (!/^[a-zA-Z][0-9a-zA-Z_]{1,9}$/.test(username)) {
    next('User name can only contain array letters, underscores, length 2~10 Bit, beginning with a letter');
  } else if (!/^\S{6,12}$/.test(password)) {
    next('Password 6~12 Bits and no spaces');
  } else {
    next();
  }
});

Error handling Middleware

// Error handling Middleware
router.use((err, req, res, next) => {
  // err is the parameter value from next
  res.send({ status: 1, message: err })
});

Code implementation authentication

Download and install:

npm i express-jwt 
const jwt = require('express-jwt');
// app.use(jwt().unless());
// jwt() is used to parse the token and assign the data saved in the token to req.user
// unless() completes authentication
app.use(jwt({
  secret: 'sfsws23s', // The keys when generating token s must be unified
  algorithms: ['HS256'] // Required, encryption algorithm, no need to know
}).unless({
  path: ['/api/login', '/api/reguser'] // In addition to these two interfaces, other interfaces need authentication
}));

After the above code is completed, when a request is sent to the server, the Authorization field in the request header will be verified

If there is no problem

   Assign the user id saved in the token to req.user

  next().

Therefore, it is also necessary to add error handling middleware at the end of index.js to prompt token errors

app.use((err, req, res, next) => {
  if (err.name === 'UnauthorizedError') {
    // res.status(401).send('invalid token...');
    res.status(401).send({ status: 1, message: 'Identity authentication failed!' });
  }
});

Case - personal center interface

Using routing module   / routers/user.js

// user routing file
const express = require('express');
const router = express.Router();


// export
module.exports = router;

Load the routing module in index.js and register the middleware

app.use('/my/user', require('./routers/user'));

Get user information interface

// ***************************Get user information***************************/
/**
 * Request method: GET
 * Interface address: / my/user/userinfo
 * Parameter: None
 */
router.get('/userinfo', (req, res) => {
  // console.log(req.user); // { id: 1, iat: 1611537302, exp: 1611544502 }
  // return;
  // Query the information of the current login account, not everyone's information
  db('select * from user where id=' + req.user.id, (err, result) => {
    if (err) throw err;
    res.send({
      status: 0,
      message: 'User information obtained successfully',
      data: result[0]
    })
  });
});

Replace avatar interface

// ***************************Replace avatar interface***************************/
/**
 * Request method: POST
 * Interface address: / my/user/avatar
 * Content-Type: application/x-www-form-urlencoded
 * Request body: avatar
 */
router.post('/avatar', (req, res) => {
  // console.log(req.body); // { avatar: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHg' }
  let sql = `update user set user_pic='${req.body.avatar}' where id=${req.user.id}`;
  db(sql, (err, result) => {
    if (err) throw err;
    res.send({ status: 0, message: 'Successfully replaced the Avatar' })
  })
});

Case article related interface

Using routing module   / routers/article.js

// category routing file
const express = require('express');
const router = express.Router();


// export
module.exports = router;

Load the routing module in index.js and register the middleware

app.use('/my/article', require('./routers/article'));

Paging get article interface

// ----------------Paging to get the article list----------------
// Interface requirements:
/**
 * Request method: GET
 * Requested url: / my/article/list
 * Request parameters:
 *  - pagenum -- Page number value
 *  - pagesize -- How many pieces of data are displayed per page
 *  - cate_id -- Id of article classification
 *  - state -- Status of the article, either draft or published
 */
router.get('/list', (req, res) => {
    // console.log(req.query);
    // Set variables and receive request parameters
    let { pagenum, pagesize, cate_id, state } = req.query;
    // console.log(cate_id, state);
    // According to cat_ ID and state are the conditions for making SQL statements
    let w = '';
    if (cate_id) {
        w += ` and cate_id=${cate_id} `;
    }
    if (state) {
        w += ` and state='${state}' `;
    }
    // SQL for paging query data (this SQL uses linked table query and uses many variable combinations)
    let sql1 = `select a.id, a.title, a.state, a.pub_date, c.name cate_name from article a
    join category c on a.cate_id=c.id
    where author_id=${req.user.id} and is_delete=0 ${w}
    limit ${(pagenum - 1) * pagesize}, ${pagesize}`;
    // Query the SQL of total records. The query criteria must be consistent with the previous query data
    let sql2 = `select count(*) total from article a
    join category c on a.cate_id=c.id
    where author_id=${req.user.id} and is_delete=0 ${w}`;
    // Execute two SQL queries respectively (because db query database is an asynchronous method, you must nest queries)
    db(sql1, (err, result1) => {
        if (err) throw err;
        db(sql2, (e, result2) => {
            if (e) throw e;
            res.send({
                status: 0,
                message: 'Successfully obtained article list data',
                data: result1,
                total: result2[0].total
            });
        })
    })
});

Add article interface

This is an interface whose request body is of type FormData.

Installation: npm i multer

Load: const multer= require('multer ')

Configuration upload file path: const upload = multer ({desc: 'uploads /'})

Used in the interface:

router.post('/add', upload.single('cover_img'), (req, res) => {
  // The upload.single() method is used to handle single file upload
  // cover_ Name of img picture field
  
  // Receive the request body of text type through req.body, such as title,content, etc
  // Get the uploaded file information through req.file
});
var multer = require('multer')
var upload = multer({ dest: 'uploads/' }); // Configure the directory of uploaded files
const moment = require('moment');

router.post('/add', upload.single('cover_img'), (req, res) => {
  // req.body represents text information
  // req.file indicates the uploaded file information
  // console.log(req.file); // req.file.filename indicates the file name after uploading

  // Add data to the data table and save it
  // req.body = { title: 'xx', content: 'xx', cate_id: 1, state: 'xx' }
  let { title, content, cate_id, state } = req.body; 
  // Other fields
  let pub_date = moment().format('YYYY-MM-DD HH:mm:ss');
  let cover_img = req.file.filename;
  let author_id = req.user.id;
  // console.log(obj);
  // return;
  let sql = `insert into article set title='${title}', content='${content}', cate_id=${cate_id}, state='${state}', pub_date='${pub_date}', cover_img='${cover_img}', author_id=${author_id}`;
  db(sql (err, result) => {
    if (err) throw err;
    if (result.affectedRows > 0) {
      res.send({ status: 0, message: 'Published successfully' })
    } else {
      res.send({ status: 1, message: 'Publishing failed' })
    }
  })
});

Delete article interface

// ----------------Delete file interface--------------------
/**
 * Request method: GET
 * Interface address: / my/article/delete/2
 * Request parameters: id, url parameters
 */
// router.get('/delete/:id/:age/:name', (req, res) => {
router.get('/delete/:id', (req, res) => {
  let id = req.params.id;
  let sql = `update article set is_delete=1 where id=${id} and author_id=${req.user.id}`;
  db(, (err, result) => {
    if (err) throw err;
    if (result.affectedRows > 0) {
      res.send({ status: 0, message: 'Delete succeeded' })
    } else {
      res.send({ status: 1, message: 'Deletion failed' })
    }
  })
});

Update article interface

router.post('/update', upload.single('cover_img'), (req, res) => {
  // It's similar to adding an article interface. Note that the client submits more article IDS, which is the condition for us to modify the article
  // req.body = { title: 'xx', content: 'xx', cate_id: 1, state: 'xx', id: 6 }
  let { title, content, cate_id, state, id } = req.body; 
  // Other fields (release time, not modification time, so it does not need to be changed, and the user id does not need to be changed)
  let cover_img = req.file.filename;
  // console.log(obj);
  // return;
  let sql = `update article set title='${title}', content='${content}', cate_id=${cate_id}, state='${state}', cover_img='${cover_img}' where id=${id}`;
  db(sql, (err, result) => {
    if (err) throw err;
    if (result.affectedRows > 0) {
      res.send({ status: 0, message: 'Article modified successfully' })
    } else {
      res.send({ status: 1, message: 'Failed to modify article' })
    }
  })
});

Express summary:

 

Posted by dey.souvik007 on Sat, 18 Sep 2021 10:18:58 -0700