Express接口综合案例(创建项目、配置常用中间件、路由设计、提取控制器模块、配置错误统一处理中间件、用户注册的数据验证,密码加密)
一、创建项目
二、目录结构
三、配置常用中间件
3.1 解析请求体
- express.json()
- express.urlencoded()
3.2 日志输出
- morgan()
3.3 为客户端提供跨域资源请求
- cors()
四、路由设计
本项目的接口设计参考: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')
})// 用户相关的路由
router.use(require('./user.js'))// 用户资料相关路由
router.use(require('./profile.js'))// 文章相关的路由
router.use(require('./article.js'))// 标签相关的路由
router.use(require('./tag.js'))module.exports = router
router/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)// 获取当前登录用户
router.get('/user', userController.getCurrentUser)// 更新当前登录的用户资料
router.put('/user', userController.updateCurrentUser)module.exports = router
router/article.js:
const express = require('express')
const articleController = require('../controller/article.js')
const router = express.Router()// 获取文章列表
router.get('/articles', articleController.getArticles)// 获取用户关注的作者的文章列表
router.get('/articles/feed', articleController.getFeedArticles)// 获取文章
router.get('/articles/:slug', articleController.getArticle)// 创建文章
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 = router
router/profile.js:
const express = require('express')
const profileController = require('../controller/profile.js')
const router = express.Router()// 获取用户个人资料
router.get('/profiles/:username', profileController.getProfile)// 关注用户
router.post('/profiles/:username/follow', profileController.followUser)// 取消关注用户
router.delete('/profiles/:username/follow', profileController.unFollowUser)module.exports = router
router/tag.js:
const express = require('express')
const tagsController = require('../controller/tag.js')
const router = express.Router()// 获取文章标签
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. 获取请求体数据console.log(req.body)// 2. 数据验证// 2.1 基本数据验证// 2.2 业务数据验证// 3. 验证通过,将数据保存到数据库const user = new User(req.body.user) // 构造user对象await user.save() // 保存到数据库// 4. 发送成功响应res.status(201).json({user})} catch (err) {next(err)}
}// 获取当前登录用户
exports.getCurrentUser = async (req, res, next) => {try {// 处理请求res.send('get /user')} catch (err) {next(err)}
}// 更新当前登录的用户资料
exports.updateCurrentUser = async (req, res, next) => {try {// 处理请求res.send('put /user')} catch (err) {next(err)}
}
controller/tag.js:
// 获取文章标签
exports.getTags = async (req, res, next) => {try {// 处理请求res.send('get /tags 获取文章标签')} catch (err) {next(err)}
}
controller/article.js:
// 获取文章列表
exports.getArticles = async (req, res, next) => {try {// 处理请求res.send('get /articles')} catch (err) {next(err)}
}// 获取用户关注的作者的文章列表
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)}
}// 创建文章
exports.createArticle = async (req, res, next) => {try {// 处理请求res.send('post /articles 创建文章')} 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)}
}// 关注用户
exports.followUser = async (req, res, next) => {try {// 处理请求res.send('post /profiles/:username/follow')} catch (err) {next(err)}
}// 取消关注用户
exports.unFollowUser = async (req, res, next) => {try {// 处理请求res.send('delete /profiles/:username/follow')} catch (err) {next(err)}
}
六、配置错误统一处理中间件
七、用户注册 将数据保存到数据库 && 提取通用数据模型
model/index.js:
model/user.js:
model/article.js:
model/base-model.js:
八、数据验证
express-validator官方文档
安装:npm install express-validator
九、提取验证中间件模块
十、用户注册的密码加密处理
nodejs内置模块 crypto 模块
提供了加密功能,实现了包括对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。
- 查看 crypto 模块支持的 hash 函数:crypto.getHashes()
在模型的password字段上进行md5加密:
关于Model模型中字段的一些属性:
type:字段的类型;
require:true或false,指定该字段是否必填(默认false,不是必填的);
max与min:数字,只能用在Number类型,可以表示最大值与最小值是多少;
maxlength与minlength:只能用于String字符串类型,表示最长或最短字符串长度;
enum: [‘男’, ‘女’],可枚举类型,后边是一个数组,也就是值必须在枚举值中,并且枚举类型必须是String;
例:sex: { type: String, enum: [ ‘男’, ‘女’ ] } sex字段的值必须在枚举值中,且必须为字符串。
defalt: ‘xxx’, 默认值,如果没有传参数时,会取默认值,存入数据库。
trim: true, 去除字符串两端空格(保存前对字段进行 .trim());
uppercase:true , 只能用于字符串,表示把所有小写字母转为大写字母(保存前对字段进行.toUpperCase());
lowercase:true , 只能用于字符串,表示把所有大写字母转为小写字母(保存前对字段进行.toLowerCase());
例:test{ type: String, lowercase: true }。
select: true/false,指定该字段在查询出的数据中是否显示,true表示查询数据过滤该字段;
get: () => {} 和set:() => {},两个函数使用Object.defineProperty( ) 来定义getter、setter。
validate: ()=>{ } ,为该字段添加校验。
Express接口综合案例(创建项目、配置常用中间件、路由设计、提取控制器模块、配置错误统一处理中间件、用户注册的数据验证,密码加密)相关推荐
- QT 基础知识一(QT安装、创建项目、常用窗口控件使用、信号与槽机制讲解)
QT概念 Qt:Qt是一个跨平台的C++框架(C++库),Qt除了支持界面设计(GUI编程),还封装了与网络编程.多线程.数据库连接.视频音频等相关的功能. ctrl 撤销(返回上一步) 市面常见的G ...
- 网络拓扑配置案例练习(VRRP,浮动路由,DHCP,三层交换机配置)
网络拓扑配置案例 网络拓扑配置案例练习 网络拓扑 需求描述 具体操作命令 交换机创建vlan,配置access.trunk口,划分vlan vrrp配置 路由配置 验证vrrp和浮动路由 DHCP配置 ...
- 计算机硬件选配用户需求,设计师选什么样的电脑配置?浅谈设计用电脑硬件配置的选择建议...
设计师选什么样的电脑配置?对于这个问题,无法给一个准确的回答,主要是因为设计分为很多种,比如平面设计.3D工业设计.视频动画设计等,由于用途不一,对电脑配置的要求也不一样.下面装机之家来浅谈设计用电脑 ...
- 视频教程-Web前端开发仿美团/饿了吗移动App之高德地图接口对接案例-JavaScript
Web前端开发仿美团/饿了吗移动App之高德地图接口对接案例 互联网编程行业10年开发和授课经验 曾任太极集团,外资企业等一线互联网python高级开发工程师 现任聚焦计算机技术有限公司项目组担任架构 ...
- 5.19 综合案例2.0-智能风扇(仅支持2.2以上版本)
综合案例2.0-智能风扇 简介 AHT10温湿度传感器 电机模块 准备 硬件连接图 代码流程 功能实现 1.物联网平台开发 2.设备端开发 调试 3.物联网应用开发 3.1新建'普通项目' 3.2关联 ...
- VUE——使用VUE脚手架创建项目
前言 vue脚手架工具,对vue项目构造做了封装,直接使用vue-cli创建项目,常用配置自动帮你完成,不用自己像使用webpack一样配置. 目录 1.安装 npm i vue 2.创建vue项目 ...
- 如何使用 Maven 来创建项目(一篇文章就够了)
如何使用 Maven 来创建项目(一篇文章就够了) 1. Maven 简介 1. 简介 2. 项目构建 3. 项目构建工具 2. Maven 的四大特性 1. 依赖管理系统 版本号规范 2. 多模块构 ...
- 项目起步 (一) 01-项目介绍-使用技术-创建项目-调整目录结构——黑马头条移动端
项目介绍 首先,黑马头条移动端是一个IT资讯移动web应用,有着和今日头条一样的资讯浏览体验. 主要功能:资讯列表.标签页切换,文章举报,频道管理.离线频道,文章详情.阅读记忆,关注功能.点赞功能.评 ...
- vue创建项目都忘记了怎么办
公司给了一个比较特殊的项目,不需要使用编写前端,其他几乎都是纯后端,只有很少的几个前端页面,我还是用的LayUI+JQuery做的后台页面,没做多久就看到了LayUI下线的说明,有点蕾姆~~~~~,对 ...
最新文章
- 上海交大机试真题—最短路径(最小生成树解法)
- Windows核心编程的官方网站
- matlab绘制立体图
- 如何判断一个点是否在三角形内部
- Linux安装docker-compose 1.27.4
- 汇编中断知识之INT 1CH
- ‘仿微信发表朋友圈’项目中登录功能的业务逻辑
- bash 后台程序_如何向您的Bash程序添加帮助工具
- linux下tomcat ssl证书,Tomcat部署ssl证书(Linux)
- 用winformz时间格式不正确_巨峰葡萄不能膨大?错!在正确的时间,用对方法,收获优质果穗型...
- 冲刺秋招!离拿到心仪Offer你还差什么?
- java翻译数字串并打印_如何使用Java翻译字符串?
- JAVA_WEB程序设计教程 pdf
- 指标公式c语言源码下载,通达信超级全系列指标公式
- 喜马拉雅下载文件名批量修改
- 如何在家优雅地使用 Sci-Hub 免费下载外文文献
- 二元二次不定方程(佩尔方程)
- 用c++随机生成10小学生算术题的课设
- Linux du命令详解
- 一般对称性和轮换对称性
热门文章
- ubuntu之ufw防火墙
- HIVE攻略 JFK_Hive安装及使用攻略
- redhat虚拟机安装
- Windows API GetProcAddress 及demo code
- w3wp oracle,w3wp.exe占用CPU超过50%的处理
- qlabel可以选中吗_惊现凡尔赛式排版!原来微信公众号排版样式还可以“变装”?...
- python 编程模型
- caffe运行训练脚本时报错:Unknown bottom blob 'data' (layer 'conv1',bottom index 0)
- C++之Boost准标准库配置
- python知识点1