Express接口综合案例(创建项目、配置常用中间件、路由设计、提取控制器模块、配置错误统一处理中间件、用户注册的数据验证,密码加密)
一、創(chuàng)建項(xiàng)目
二、目錄結(jié)構(gòu)
三、配置常用中間件
3.1 解析請求體
- express.json()
- express.urlencoded()
3.2 日志輸出
- morgan()
3.3 為客戶端提供跨域資源請求
- cors()
四、路由設(shè)計
本項(xiàng)目的接口設(shè)計參考:https://github.com/gothinkster/realworld/tree/master/api
router/index.js:
const express = require('express')const router = express.Router()router.get('/', (req, res) => {res.send('Hello World') })// 用戶相關(guān)的路由 router.use(require('./user.js'))// 用戶資料相關(guān)路由 router.use(require('./profile.js'))// 文章相關(guān)的路由 router.use(require('./article.js'))// 標(biāo)簽相關(guān)的路由 router.use(require('./tag.js'))module.exports = routerrouter/user.js:
const express = require('express') const userController = require('../controller/user.js') const router = express.Router()// 用戶登錄 router.post('/users/login', userController.login)// 用戶注冊 router.post('/users', userController.register)// 獲取當(dāng)前登錄用戶 router.get('/user', userController.getCurrentUser)// 更新當(dāng)前登錄的用戶資料 router.put('/user', userController.updateCurrentUser)module.exports = routerrouter/article.js:
const express = require('express') const articleController = require('../controller/article.js') const router = express.Router()// 獲取文章列表 router.get('/articles', articleController.getArticles)// 獲取用戶關(guān)注的作者的文章列表 router.get('/articles/feed', articleController.getFeedArticles)// 獲取文章 router.get('/articles/:slug', articleController.getArticle)// 創(chuàng)建文章 router.post('/articles',articleController.createArticle)// 更新文章 router.put('/articles/:slug', articleController.updateArticle)// 刪除文章 router.delete('/articles/:slug', articleController.deleteArticle)// 為文章添加評論 router.post('/articles/:slug/comments', articleController.addComments)// 從文章中獲取評論 router.get('/articles/:slug/comments', articleController.getComments)// 刪除評論 router.delete('/articles/:slug/comments/:id', articleController.deleteComments)// 收藏文章 router.post('/articles/:slug/favorite', articleController.favoriteArticle)// 取消收藏文章 router.delete('/articles/:slug/favorite', articleController.unFavoriteArticle)module.exports = routerrouter/profile.js:
const express = require('express') const profileController = require('../controller/profile.js') const router = express.Router()// 獲取用戶個人資料 router.get('/profiles/:username', profileController.getProfile)// 關(guān)注用戶 router.post('/profiles/:username/follow', profileController.followUser)// 取消關(guān)注用戶 router.delete('/profiles/:username/follow', profileController.unFollowUser)module.exports = routerrouter/tag.js:
const express = require('express') const tagsController = require('../controller/tag.js') const router = express.Router()// 獲取文章標(biāo)簽 router.get('/tags', tagsController.getTags)module.exports = router五、提取控制器模塊
controller/user.js:
const { User } = require('../model/index.js')// 用戶登錄 exports.login = async (req, res, next) => {try {// 處理請求res.send('post /users/login')} catch (err) {next(err)} }// 用戶注冊 exports.register = async (req, res, next) => {try {// 1. 獲取請求體數(shù)據(jù)console.log(req.body)// 2. 數(shù)據(jù)驗(yàn)證// 2.1 基本數(shù)據(jù)驗(yàn)證// 2.2 業(yè)務(wù)數(shù)據(jù)驗(yàn)證// 3. 驗(yàn)證通過,將數(shù)據(jù)保存到數(shù)據(jù)庫const user = new User(req.body.user) // 構(gòu)造user對象await user.save() // 保存到數(shù)據(jù)庫// 4. 發(fā)送成功響應(yīng)res.status(201).json({user})} catch (err) {next(err)} }// 獲取當(dāng)前登錄用戶 exports.getCurrentUser = async (req, res, next) => {try {// 處理請求res.send('get /user')} catch (err) {next(err)} }// 更新當(dāng)前登錄的用戶資料 exports.updateCurrentUser = async (req, res, next) => {try {// 處理請求res.send('put /user')} catch (err) {next(err)} }controller/tag.js:
// 獲取文章標(biāo)簽 exports.getTags = async (req, res, next) => {try {// 處理請求res.send('get /tags 獲取文章標(biāo)簽')} catch (err) {next(err)} }controller/article.js:
// 獲取文章列表 exports.getArticles = async (req, res, next) => {try {// 處理請求res.send('get /articles')} catch (err) {next(err)} }// 獲取用戶關(guān)注的作者的文章列表 exports.getFeedArticles = async (req, res, next) => {try {// 處理請求res.send('get /articles/feed')} catch (err) {next(err)} }// 獲取文章 exports.getArticle = async (req, res, next) => {try {// 處理請求res.send('get /articles/:slug 獲取文章')} catch (err) {next(err)} }// 創(chuàng)建文章 exports.createArticle = async (req, res, next) => {try {// 處理請求res.send('post /articles 創(chuàng)建文章')} catch (err) {next(err)} }// 更新文章 exports.updateArticle = async (req, res, next) => {try {// 處理請求res.send('put /articles/:slug 更新文章')} catch (err) {next(err)} }// 刪除文章 exports.deleteArticle = async (req, res, next) => {try {// 處理請求res.send('delete /articles/:slug 刪除文章')} catch (err) {next(err)} }// 為文章添加評論 exports.addComments = async (req, res, next) => {try {// 處理請求res.send('post /articles/:slug/comments 為文章添加評論')} catch (err) {next(err)} }// 從文章中獲取評論 exports.getComments = async (req, res, next) => {try {// 處理請求res.send('get /articles/:slug/comments 從文章中獲取評論')} catch (err) {next(err)} }// 刪除評論 exports.deleteComments = async (req, res, next) => {try {// 處理請求res.send('delete /articles/:slug/comments/:id 刪除評論')} catch (err) {next(err)} }// 收藏文章 exports.favoriteArticle = async (req, res, next) => {try {// 處理請求res.send('post /articles/:slug/favorite 收藏文章')} catch (err) {next(err)} }// 取消收藏文章 exports.unFavoriteArticle = async (req, res, next) => {try {// 處理請求res.send('delete /articles/:slug/favorite 取消收藏文章')} catch (err) {next(err)} }controller/profile.js:
// 獲取用戶個人資料 exports.getProfile = async (req, res, next) => {try {// 處理請求res.send('get /profiles/:username')} catch (err) {next(err)} }// 關(guān)注用戶 exports.followUser = async (req, res, next) => {try {// 處理請求res.send('post /profiles/:username/follow')} catch (err) {next(err)} }// 取消關(guān)注用戶 exports.unFollowUser = async (req, res, next) => {try {// 處理請求res.send('delete /profiles/:username/follow')} catch (err) {next(err)} }六、配置錯誤統(tǒng)一處理中間件
七、用戶注冊 將數(shù)據(jù)保存到數(shù)據(jù)庫 && 提取通用數(shù)據(jù)模型
model/index.js:
model/user.js:
model/article.js:
model/base-model.js:
八、數(shù)據(jù)驗(yàn)證
express-validator官方文檔
安裝:npm install express-validator
九、提取驗(yàn)證中間件模塊
十、用戶注冊的密碼加密處理
nodejs內(nèi)置模塊 crypto 模塊提供了加密功能,實(shí)現(xiàn)了包括對 OpenSSL 的哈希、HMAC、加密、解密、簽名、以及驗(yàn)證功能的一整套封裝。
- 查看 crypto 模塊支持的 hash 函數(shù):crypto.getHashes()
在模型的password字段上進(jìn)行md5加密:
關(guān)于Model模型中字段的一些屬性:
type:字段的類型;
require:true或false,指定該字段是否必填(默認(rèn)false,不是必填的);
max與min:數(shù)字,只能用在Number類型,可以表示最大值與最小值是多少;
maxlength與minlength:只能用于String字符串類型,表示最長或最短字符串長度;
enum: [‘男’, ‘女’],可枚舉類型,后邊是一個數(shù)組,也就是值必須在枚舉值中,并且枚舉類型必須是String;
例:sex: { type: String, enum: [ ‘男’, ‘女’ ] } sex字段的值必須在枚舉值中,且必須為字符串。
defalt: ‘xxx’, 默認(rèn)值,如果沒有傳參數(shù)時,會取默認(rèn)值,存入數(shù)據(jù)庫。
trim: true, 去除字符串兩端空格(保存前對字段進(jìn)行 .trim());
uppercase:true , 只能用于字符串,表示把所有小寫字母轉(zhuǎn)為大寫字母(保存前對字段進(jìn)行.toUpperCase());
lowercase:true , 只能用于字符串,表示把所有大寫字母轉(zhuǎn)為小寫字母(保存前對字段進(jìn)行.toLowerCase());
例:test{ type: String, lowercase: true }。
select: true/false,指定該字段在查詢出的數(shù)據(jù)中是否顯示,true表示查詢數(shù)據(jù)過濾該字段;
get: () => {} 和set:() => {},兩個函數(shù)使用Object.defineProperty( ) 來定義getter、setter。
validate: ()=>{ } ,為該字段添加校驗(yàn)。
總結(jié)
以上是生活随笔為你收集整理的Express接口综合案例(创建项目、配置常用中间件、路由设计、提取控制器模块、配置错误统一处理中间件、用户注册的数据验证,密码加密)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三、Java Web中出现的一些乱码问题
- 下一篇: OSPF协议及链路状态算法(详解)