一、NodeApi 環境搭建
創建文件夾
新建一個文件夾 nodeApi
在本地終端運行
npm init
創建一個package.json 文件
修改 package.json
"scripts": {
"start": "node server"
},
將原來的test啟動命令修改為現在的dev,node server的意思是用node啟動本地文件server.js,所以我們要在當前文件夾下在創建一個server.js
安裝依賴
在本地終端運行
cnpm install express dotenv --save
//如果你沒有全局安裝過nodemon,需要先全局安裝一次
cnpm install -g nodemon
//然后在開發環境安裝
cnpm install -D nodemon
修改package.json,添加一個用nodemon啟動項目的新命令
"dev":"nodemon server"
npm安裝比較慢,這里我是用淘寶源來安裝我們搭建本次項目所需要的環境依賴。
其中express是node的一個框架,每次修改文件都需要重啟服務器,所以我們需要nodemon來幫助我們重啟。
而dotenv呢?由於項目不同需求,需要配置不同環境變量,按需加載不同的環境變量文件,使用dotenv,可以完美解決這一問題。
創建環境變量
在當前目錄下新建文件夾config,在config文件夾下新建文件config.env
NODE_ENV=development
PORT=5000
復制上述代碼到新創建的文件下
修改package.json文件
"start": "NODE_ENV=production node server",
當等於生產環境的時候,讓我們運行 node server來啟動項目
引入依賴和環境變量並使用
const express = require("express")
const dotenv = require("dotenv")
dotenv.config({
path:'./config/config.env',
});
const app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT,console.log(`Server rnning in ${process.env.NODE_ENV} mode on port ${PORT}`))
運行 npm run dev 會發現我們運行成功,監聽到的是5000端口,這說明環境變量的和依賴的引入沒有問題
創建路由
下面是Node接收get請求返回數據的幾種方式
// http://localhost:5000/
app.get("/",(req,res)=>{
// res.send("<h1>Hello World</h1>") 發送HTML
// res.send({mag:"Hello World"}) 發送json格式數據
// res.json({success:true}) 發送json格式數據
// res.sendStatus(400) 發送狀態碼
res.status(200).json({success:true,msg:"Hello World"}) //發送狀態碼和json數據
})
上面我們訪問的都是根路徑,現在我們嘗試給他新的路由地址及嘗試新的請求方法
// http://localhost:5000/api:id
app.get("/api/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}獲取單個數據`})
})
// http://localhost:5000/api
app.post("/api",(req,res)=>{
res.status(200).json({success:true,msg:`創建新的數據`})
})
// http://localhost:5000/api:id
app.put("/api/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}更新數據`})
})
// http://localhost:5000/api:id
app.delete("/api/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}刪除數據`})
})
路由文件分離
前面我們做到了創建各種接口,可以想象一下,如果項目足夠大的話,把接口放在一起,是不是很不利於維護,接下來我們要做的就是把路由文件分離,拆分成一小塊一小塊。
在當前目錄下新建routes文件夾,在routes文件夾下新建api.js,其中routes用來存放我們所有的接口,api文件存放訪問/api這個路徑下的接口
完整代碼如下:
/routes/api.js
const express = require("express")
const router = express()
router.get("/",(req,res)=>{
res.status(200).json({success:true,msg:"獲取所有數據"})
})
router.get("/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}獲取單個數據`})
})
router.post("/",(req,res)=>{
res.status(200).json({success:true,msg:`創建新的數據`})
})
router.put("/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}更新數據`})
})
router.delete("/:id",(req,res)=>{
res.status(200).json({success:true,msg:`根據${req.params.id}刪除數據`})
})
module.exports = router
server.js
const express = require("express")
const dotenv = require("dotenv")
const app = express()
dotenv.config({
path:'./config/config.env',
});
const api = require("./routes/api")
app.use('/api',api)
const PORT = process.env.PORT || 3000;
app.listen(PORT,console.log(`Server rnning in ${process.env.NODE_ENV} mode on port ${PORT}`))
上述代碼中,我們通過require將api引入到了server.js中,並通過app.use()這個方法掛載到當訪問/api路徑時,將通過api這個文件來處理請求。
優化路由
在api.js中,我們可以看到盡管請求方法不一樣,但請求的路徑大多相同,現在讓我們來優化一下吧
在當前目錄下新建文件夾controllers,在controllers文件夾下新建api.js,代碼如下:
/controllers/api.js
exports.getApis = (req,res,next) => {
res.status(200).json({success:true,msg:"獲取所有數據"});
}
exports.createApi = (req,res,next) => {
res.status(200).json({success:true,msg:`創建新的數據`})
}
exports.getApi = (req,res,next) => {
res.status(200).json({success:true,msg:`根據${req.params.id}獲取單個數據`})
}
exports.updateApi = (req,res,next) => {
res.status(200).json({success:true,msg:`根據${req.params.id}更新數據`})
}
exports.deleteApi = (req,res,next) => {
res.status(200).json({success:true,msg:`根據${req.params.id}刪除數據`})
}
在 /routes/api.js 引入剛剛創建的文件並修改代碼
const express = require("express")
const router = express()
//引入控制器
const {getApis,createApi,getApi,updateApi,deleteApi} = require('../controllers/api')
router.route("/").get(getApis).post(createApi)
router.route("/:id").get(getApi).put(updateApi).delete(deleteApi)
module.exports = router
可以看到我們的代碼明顯簡潔了許多
中間件
安裝margan
cnpm install margan --save
在server.js下使用
// 引入morgan中間件
const morgan = require('morgan')
// 使用morgan中間件
app.use(morgan("dev"))
使用 morgan中間件 可以將請求信息打印在控制台,便於開發調試
安裝colors
cnpm i colors --save
在server.js下使用
app.listen(PORT,console.log(`Server rnning in ${process.env.NODE_ENV} mode on port ${PORT}`.magenta.bold))
使用 colors 可以改變打印信息的顏色
連接mongodb數據庫
cnpm i mongoose --save
在config.env 加一個連接mongodb數據庫地址的環境變量
mongodb://127.0.0.1:27017
在config新建db.js
const mongoose = require('mongoose')
const connectDB = async () => {
const conn = await mongoose.connect(process.env.NET_MONGO_URI, {
//避免警告信息
useNewUrlParser: true,
useUnifiedTopology:true,
useCreateIndex:true,
useFindAndModify:false
});
console.log(`MongoDB Connected: ${conn.connection.host}`.blue.bold);
}
module.exports = connectDB
在server.js中啟動數據庫
const connectDB = require('./config/db')
...
// 鏈接數據庫
connectDB()
連接mongodb數據庫錯誤處理
process.on("unhandledRejection",(err,promise) => {
console.log(`Error:${err.message}`.red.bold);
//關閉服務器 & 退出進程
server.colors(() => {
process.exit(1)
})
})
對於mongoose不熟悉的可以查閱這篇文章:mongoose中文教程
二、搭建用戶數據
創建數據模型
在當前目錄下新建文件夾models,在文件夾下新建UserInfo.js
const mongoose = require("mongoose");
const UserInfoSchema = new mongoose.Schema({
name: {
type: String, //類型
require: [true, '請填寫用戶名'], //是否必須填寫
unique: true, //是否唯一
trim: true, //去掉空格
maxlength: [20, '用戶名不能超過20個字'] //最大長度
},
description: {
type: String,
require: [true, '請填寫個人簡介'],
maxlength: [500, '個人簡介不能超過500個字']
},
website: {
type: String,
match: [/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/, '請填寫合法的網址'], //正則匹配
},
phone: {
type: String,
match: [/^[1][3,4,5,7,8][0-9]{9}$/, '請填寫正確的手機號'],
},
email: {
type: String,
match: [/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/, '請填寫正確的郵箱地址'],
},
address: {
type: String,
default: '江西省撫州市臨川區' //默認值
},
address: {
type: String,
default: '江西省撫州市臨川區' //默認值
},
occupation: {
type: String,
default: '前端開發工程師'
},
skill: {
type: Array,
default: ['html', 'js', 'css', 'vue', 'react', 'node.js']
},
createdAt:{
type:Date,
default:Date.now
}
})
module.exports = mongoose.model('UserInfo',UserInfoSchema)