今天,我們著手做一個倉儲管理,原材入庫的模塊,以實際的項目來進一步了解node.js,學以致用,反補理論知識。
工程結構
創(chuàng)建一個倉儲管理的原材入庫模塊,使用Node.js作為后端服務,可以采用以下工程結構:
warehouse-management/
├── node_modules/ # 依賴的npm包
├── src/ # 源代碼目錄
│ ├── controllers/ # 控制器目錄
│ │ └── material.js # 原材入庫控制器
│ ├── models/ # 數(shù)據(jù)模型目錄
│ │ └── material.js # 原材入庫模型
│ ├── routes/ # 路由目錄
│ │ └── material.js # 原材入庫路由
│ ├── services/ # 服務目錄
│ │ └── material.js # 原材入庫服務(如數(shù)據(jù)庫操作)
│ ├── utils/ # 工具目錄
│ │ └── ... # 工具函數(shù)或類
│ ├── app.js # 主應用文件
│ └── config/ # 配置目錄
│ └── database.js # 數(shù)據(jù)庫配置文件
├── package.json # 項目依賴和配置
├── .gitignore # Git忽略文件
├── README.md # 項目說明文檔
└── ... # 其他可能需要的文件,如日志配置、測試文件等
以下是每個目錄和文件的簡單說明:
node_modules/
存放項目依賴的npm包。
src/
源代碼目錄,包含項目的所有核心代碼。
controllers/
存放控制器文件,這些文件負責處理HTTP請求并返回響應。material.js
將處理與原材入庫相關的請求。
models/
存放數(shù)據(jù)模型文件,這些文件定義了與數(shù)據(jù)庫表對應的對象結構。material.js
將定義原材入庫相關的數(shù)據(jù)模型。
routes/
存放路由文件,這些文件定義了URL路徑與控制器方法的映射關系。material.js
將定義原材入庫相關的路由。
services/
存放服務文件,這些文件包含與業(yè)務邏輯相關的代碼,例如數(shù)據(jù)庫操作、文件操作等。material.js
將包含與原材入庫相關的數(shù)據(jù)庫操作邏輯。
utils/
存放工具函數(shù)或類,這些函數(shù)或類在整個項目中可能都會被使用到。
app.js
主應用文件,用于初始化應用,設置中間件,加載路由等。
config/
存放配置文件,例如數(shù)據(jù)庫配置、應用環(huán)境配置等。database.js
將包含數(shù)據(jù)庫連接配置。
package.json
項目依賴和配置文件,包含項目名稱、版本、描述、腳本命令、依賴項等信息。
.gitignore
Git忽略文件,指定哪些文件和目錄不應被Git跟蹤。
README.md
項目說明文檔,包含項目的安裝、使用、配置等說明。
其他文件
可能還包括日志文件配置、測試文件等,在這里我們先不配置,后期有需要再加。
大家注意,前期設計一個工程的時候要綜合考慮投產(chǎn)比,并不一定是最全的就是最好的,最合適的才是最好的
工程代碼
以下是基于上述工程結構,每個目錄和文件中可能包含的代碼:
src/controllers/material.js
const MaterialService = require('../services/material');
class MaterialController {
async createMaterial(req, res) {
try {
const material = await MaterialService.createMaterial(req.body);
res.status(201).json(material);
} catch (error) {
res.status(500).json({ message: 'Error creating material' });
}
}
// 可以添加其他與材料入庫相關的控制器方法
}
module.exports = new MaterialController();
src/models/material.js
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../config/database');
const Material = sequelize.define('material', {
materialCode: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
description: {
type: DataTypes.STRING,
allowNull: false
},
quantity: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0
},
// 可以添加其他字段
}, {
timestamps: true
});
module.exports = Material;
src/routes/material.js
const express = require('express');
const router = express.Router();
const MaterialController = require('../controllers/material');
router.post('/materials', MaterialController.createMaterial);
// 可以添加其他與材料入庫相關的路由
module.exports = router;
src/services/material.js
const Material = require('../models/material');
class MaterialService {
async createMaterial(materialData) {
const material = await Material.create(materialData);
return material;
}
// 可以添加其他與材料入庫相關的服務方法
}
module.exports = new MaterialService();
src/app.js
const express = require('express');
const bodyParser = require('body-parser');
const materialRoutes = require('./routes/material');
const app = express();
app.use(bodyParser.json());
app.use('/api', materialRoutes);
// 可以添加其他中間件和路由
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
src/config/database.js
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql', // 根據(jù)你的數(shù)據(jù)庫類型選擇 'mysql' | 'mariadb' | 'postgres' | 'mssql' 等
logging: false // 在生產(chǎn)環(huán)境中,你可能想要禁用日志或將其記錄到文件
});
module.exports = sequelize;
package.json
{
"name": "warehouse-management",
"version": "1.0.0",
"description": "Warehouse Management System - Material Inbound Module",
"main": "src/app.js",
"scripts": {
"start": "node src/app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"sequelize": "^6.3.5" // 根據(jù)你的數(shù)據(jù)庫類型安裝相應的驅動,例如 'mysql2'
},
"devDependencies": {
// 開發(fā)時需要的依賴項,例如測試工具等
}
}
.gitignore
node_modules/
.env
README.md
Warehouse Management - Material Inbound Module
This is a module for managing the inbound materials in a warehouse
system.
注意事項
在上面的工程結構和代碼中,有幾個需要特別注意的注意事項:
目錄和文件結構
-
模塊化:確保每個目錄和文件都遵循單一職責原則,即每個模塊只做一件事情。這有助于代碼的可維護性和可讀性。
-
命名規(guī)范:文件名和目錄名應該使用小寫字母,多個單詞之間可以使用短橫線分隔。避免使用空格或特殊字符。
-
配置文件:配置文件(如
database.js
)應該包含敏感信息(如數(shù)據(jù)庫用戶名和密碼)的占位符,并在實際部署時通過環(huán)境變量或安全的方式提供這些值。
代碼質量
-
錯誤處理:確保所有的異步操作都有適當?shù)腻e誤處理邏輯。在上面的代碼中,我們使用了
try...catch
塊來捕獲并處理可能發(fā)生的錯誤。 -
輸入驗證:在控制器層,應該驗證所有來自客戶端的輸入數(shù)據(jù),以確保其有效性和安全性。這可以通過使用中間件或直接在控制器方法中完成。
-
日志記錄:雖然示例代碼中沒有顯式展示日志記錄,但在實際開發(fā)中,記錄重要的操作和錯誤信息是很有必要的??梢允褂脤iT的日志庫(如
winston
或pino
)來實現(xiàn)。
安全性
-
防止SQL注入:使用ORM(對象關系映射)工具(如Sequelize)可以大大減少SQL注入的風險,因為它會自動處理查詢的轉義。但是,仍然需要小心處理用戶輸入,避免直接在SQL查詢中拼接字符串。
-
保護敏感信息:不要在代碼中硬編碼敏感信息,如數(shù)據(jù)庫憑據(jù)、API密鑰等。這些信息應該通過環(huán)境變量或配置文件(確保配置文件不被公開)來提供。
-
中間件:使用中間件可以方便地處理跨多個路由的通用任務,如身份驗證、授權、日志記錄等。確保正確配置和使用中間件。
可擴展性和可維護性
-
代碼注釋:為代碼添加適當?shù)淖⑨專忉屆總€函數(shù)、類和模塊的作用和用法。這有助于其他開發(fā)者理解和維護代碼。
-
測試:編寫單元測試和功能測試以確保代碼的正確性。這有助于在代碼變更時快速發(fā)現(xiàn)并修復問題。
-
文檔:為項目編寫文檔,包括API文檔、系統(tǒng)使用說明等。這有助于其他開發(fā)者或用戶了解和使用你的系統(tǒng)。
環(huán)境配置
-
環(huán)境變量:使用環(huán)境變量來配置不同環(huán)境(如開發(fā)、測試、生產(chǎn))的設置。這可以避免在代碼中直接包含這些配置,從而提高代碼的可移植性和安全性。
-
.gitignore:確保
.gitignore
文件正確配置,以避免將敏感信息或不必要的文件提交到版本控制系統(tǒng)中。
遵循這些注意事項將有助于創(chuàng)建一個健壯、可維護和安全的倉庫管理系統(tǒng)模塊。
敏感數(shù)據(jù)-數(shù)據(jù)庫使用環(huán)境變量
敏感數(shù)據(jù)不能直接放在代碼層的配置文件中,因為這樣誰都可以看到了,是一個巨大的安全風險,要使用環(huán)境變量來配置不同環(huán)境,并在database.js
中使用它們,你可以按照以下步驟操作:
1. 設置環(huán)境變量
首先,在你的系統(tǒng)上設置環(huán)境變量。這通??梢栽诓僮飨到y(tǒng)的環(huán)境設置中進行,或者你可以在你的命令行界面中使用export
命令(在Unix/Linux/macOS中)或set
命令(在Windows中)。
例如,在Unix/Linux/macOS的bash shell中,你可以這樣做:
export DATABASE_URL="mysql://username:password@localhost:3306/database_name"
在Windows的cmd中,你可以這樣做:
set DATABASE_URL=mysql://username:password@localhost:3306/database_name
或者,在Windows的PowerShell中:
$env:DATABASE_URL="mysql://username:password@localhost:3306/database_name"
2. 在database.js中讀取環(huán)境變量
在你的Node.js項目中,你可以使用process.env
對象來訪問環(huán)境變量。在你的database.js
文件中,你可以這樣做:
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(
process.env.DATABASE_URL, // 使用環(huán)境變量中的數(shù)據(jù)庫連接字符串
{
dialectOptions: {
// 在這里,你可以添加特定于數(shù)據(jù)庫方言的選項,例如對于PostgreSQL的ssl選項
},
logging: console.log, // 或者設置為false來禁用日志,或者使用一個日志庫
// 其他Sequelize配置選項...
}
);
module.exports = sequelize;
確保你的數(shù)據(jù)庫連接字符串是正確格式的,并且與你所使用的數(shù)據(jù)庫相匹配。上面的例子是一個通用的MySQL連接字符串格式。
3. 使用.env文件(可選)
為了更方便地管理環(huán)境變量,你可以使用.env
文件來存儲這些變量,特別是在開發(fā)環(huán)境中。然后,你可以使用dotenv
庫來加載這些變量。
首先,安裝dotenv
:
npm install dotenv
然后,在你的項目根目錄下創(chuàng)建一個.env
文件,并添加你的環(huán)境變量:
DATABASE_URL=mysql://username:password@localhost:3306/database_name
在你的database.js
(或任何啟動腳本)文件的頂部,引入并使用dotenv
:
require('dotenv').config();
// 現(xiàn)在你可以像之前一樣使用process.env.DATABASE_URL了
請注意,.env
文件應該不被版本控制系統(tǒng)(如Git)跟蹤,所以確保在.gitignore
文件中添加.env
。
4. 為不同環(huán)境配置不同的變量
對于不同的環(huán)境(開發(fā)、測試、生產(chǎn)),你可以創(chuàng)建不同的.env
文件(例如.env.development
、.env.test
、.env.production
),并在你的啟動腳本中根據(jù)當前的環(huán)境加載相應的文件。
或者,你可以直接在命令行中設置不同的環(huán)境變量,并在你的CI/CD流程或部署腳本中管理它們。文章來源:http://www.zghlxwxcb.cn/news/detail-839575.html
確保在生產(chǎn)環(huán)境中,敏感信息(如數(shù)據(jù)庫憑據(jù))不會被硬編碼在代碼中,并且不會被公開或泄露。使用環(huán)境變量和.env
文件是一種安全的做法,因為這些文件通常不會被包含在代碼庫中。文章來源地址http://www.zghlxwxcb.cn/news/detail-839575.html
到了這里,關于【Node.js】-實戰(zhàn):一個簡單的倉儲管理的原材入庫模塊的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!