Anonystick

anonystick@gmail.com

Express và Node.Js xây dựng cấu trúc một dự án chuẩn?

Project Express và Node.Js - Đây là một trong số câu hỏi tuần này. Một kiến trúc tốt chưa chắc phù hợp với người này, người kia. Nhưng xét về tổng thể thì 10 người 8 người đồng ý là OK. Và đây cũng là một bài viết khởi động cho những bài viết thuộc Series - Project Structure Practices. Hy vọng các bạn sẽ có một cái nhìn tổng quan trước khi xây dựng một dự án nodejs.

Express và NodeJs


Trước tiên sẽ có một lời bàn tán xì xào, tại sao lại sử dụng "Express và Node.Js" mà không chọn những frameworks khác của Nodejs như koajs... Câu trả lời này hình như chúng ta đã có bàn luận đến ở bài viết "Vì sao lại phát triển web application sử dụng nodejs và expressjs?"


Và thêm nữa là trước đây Tipjs cũng đã giới thiệu một Series về xây dựng trang thương mại điện tử. Bạn có thể xem từ những bài viết đầu tiên.


Express là một framework dễ học và cách triển khai cũng ngắn gọn, chỉ cần một vài câu lệnh kết hợp nói Node.js là có thể open rồi. Còn nói về Node.js thì đã quá nhiều bài viết rồi. Nguyên cả một series Nodejs luôn mà. Biết dễ setup là thế nhưng, để cho hoàn chỉnh và dễ mở rộng thì có lẽ bài viết này có thể là một gợi ý cho bạn một ý tưởng thì sao?


Project structure Express and Node.Js


Hãy xem một project tốt cần có những folders nào: 


/Controllers - Thư mục này sẽ chứa tất cả các chức năng dể viết các API của bạn. Cách đặt tên: xxxxx.controller.js trong đó xxx là nhiệm vụ thôi, ví dụ: login.controller.js 

/Routes - Thư mục này sẽ chứa tất cả các tuyến đường mà bạn đã tạo bằng cách sử dụng Express Router và kết hợp với Controllers. Cách đặt tên cũng như trên xxxxx.routes.js 

/Models - Thư mục này sẽ chứa tất cả các files như schema của bạn và và các chức năng cần thiết cho schema cũng sẽ nằm ở đây. Đặt tên xxxxx.model.js /Middleware - Thư mục này sẽ chứa tất cả phần mềm trung gian mà bạn đã tạo, ví dụ như là xác thực chẳng hạn... Cách đặt tên: xxxxx.middleware.js /Utils - Các chức năng phổ biến mà bạn sẽ yêu cầu nhiều lần trong suốt mã của mình ví dụ như check missing params trước khi xử lý dữ liệu chẳng hạn. Rất cần thiết. /Configs - File này dùng cấu hình cho các API / dịch vụ của bên thứ ba như passport / S3, v.v. Những thông số như keyAPI các kiểu. 


Đó là những folders rất quan trọng, có thể nói là không thể thiếu. Ngoài ra còn những files trong root như là: 


app.js - Tệp này về cơ bản sẽ là khai báo của ứng dụng Express 

package.json - File này chứa tất cả các chi tiết npm của dự án, các lệnh chạy như scripts và các phần dependencies 

.gitignore - Những file mà bạn không muốn đẩy sang git


Cách viết các thư mục trong nodejs


Đủ rồi, giờ chúng ta đi chi tiết từng thư mục để xem cách triển khai thế nào?? Đầu tiên là Model folder. 


Models/Comments.js

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const commentSchema = new Schema({
    date: { type: Date, required: true},
    editDate: { type: Date, },
    content: { type: String },
    userId: { type: Schema.Types.ObjectId, ref: 'User', required: true }
});

module.exports = mongoose.model('Comment', commentSchema);

Controllers/Comments.js

const Comment_Model = require('../models/comment');

const getCurrentDate = () => {
  return new Date();
};

var that = module.exports = {
  postComment: async (req, res) => {
    //check params here use Utils
    const isCheck = await Utils.checkMissingParams({arrCheck, arrQuery});
    if(!isCheck){
      return res.status(200).json({
        code: 200, status: 'success', elements: 'Missing key'
      })
    }

    //nếu ok chạy tiếp 
    const isCreComment = await Comment_Model.create(req.query || req.body)
    if(!isCreComment){  
      return res.status(200).json({
        code: 200, status: 'success', elements: 'Create is Failed!!'
      })
    }

    return res.status(200).json({
        code: 200, status: 'success', elements: isCreComment._id;
    })
  }
}

Bạn nào đọc code mà không hiểu cứ mạnh dạn pm cho tipjs. Vì giải thích thì dài dòng lắm. 


Utils/index.js 


Ở đây thì dành cho những chức năng cần thiết mà được sử dụng nhiều nhất, thì viết tại đây, ví dụ trước khi đi vào xử lý dữ liệu thì các bạn nên check xem có missing params nào không?

var that = module.exports = {
  checkMissingParams: (arrCheck, arrQuery) => {
      /*
          Check missing params 
          arrCheck - params can check [LOGIN, FK100, ...]
          arrQuery - params nhan duoc tu reques [LOGIN, FK100, QV101 ...]

          return 
          {flag: false, code: `Missing ${element}`}
          {flag: true, code: 'is Okay'}
      */
      console.log('[2021]:::checkMissingParams::::', arrCheck, arrQuery);
      for (let i = 0; i < arrCheck.length; i++) {
          const element = arrCheck[i];
          if(!arrQuery.includes(element)){
              return {flag: false, code: `Missing ${element}`}
          }
      }
      return {flag: true, code: 'is Okay'}
  },
}

Middleware/index.js 


ở đây thì kiếm tra users có mang theo token không ? Nếu có thì token đúng là của nó không hay lấy của thằng khác.

var self = module.exports = {
    
    verifyToken: async (req, res, next) => {
        if (!req.headers['authorization']) {
            return res.status(400).json({
                status: 'error',
                elements: 'Missisng Token',
                code: 400
            })
        }

        let authorization = req.headers['authorization'].split(' ');
        if (authorization[0] !== 'Bearer') {
            return res.status(400).json({
                status: 'error',
                elements: 'Invalit Token split authorization',
                code: 400
            })
        }

        const isCheckToken = await tokenControl.verifyToken(req.body || req.query)
        if(!isCheckToken){
            return res.status(401).json({
                status: 'error',
                elements: 'invalid Token',
                code: 401
            })
        }
        next()
    },
    //check expried time webservice
}

Routes/comment.js 


ở đây có nhiệm vụ check token trước khi đi vào hàm postComment của file Comments.js trong Controllers.

var express = require('express');
var router = express.Router();
const {verifyToken} = require('../Middleware')
const comment = require('../controllers/comment')
router.post('/api/postComment', [verifyToken, comment.postComment]);

module.exports = router;

Còn lại app.js và hãy xem cách hướng dẫn connect database nodejs nữa nhé. Click vào mà đọc. Có yêu cầu gì thì cứ nói. Quan trọng có rất nhiều bài viết về Nodejs và Expressjs. Có thời gian thì check đi nhé mấy chế!