目录
第一章 认识Node.js
1.1 安装node
http://nodejs.cn/download/
检验是否安装完成
打开终端输入以下命令,是否出现版本号
node -vnpm -v
1.2 node示例
const os = require('os'); // 读取系统的cpu的信息const cpus = os.cpus(); //获取当前系统的cpu的数量console.log(cpus.length); //获取内存信息const total = os.totalmem();//bytesconsole.log(total/1024/1024/1024);//GB //获取剩余内存信息const free = os.freemem();console.log(free/1024/1024/1024);//GB
运行程序
终端输入
node demo.js(文件名)
1.3 第一个node程序
const http = require('http');//创建http模块const hostname = '127.0.0.1';//主机地址const port = 3000;//端口号 //创建一个server实例const server = http.createServer((req,res)=>{ //req:请求对象 //res:响应对象 res.statusCode = 200; res.setHeader('Content-Type','text/plain'); res.end('hello World');//返回到页面})server.listen(port,hostname,()=>{ //回调 console.log(`服务启动成功,监听端口:${port}`)})
页面上返回如下
终端打印如下
1.4 Supervisor介绍
我们一般都是编写代码边调试,这个过程很繁琐,Supervisor是个工具,可以帮我们自动检测代码的变化,重启服务
全局安装supervisor
npm install supervisor -g
安装完成启动项目使用
supervisor base.js(文件名)
1.5 nrm和nvm介绍
nrm管理npm源
nrm ls //查看所有的源nrm current //当前使用的源nrm use <源名称> //切换源nrm add <registry> <url> [home] //添加自定义源
安装nrm
npm install nrm -g
nvm管理node.js版本
nvm ls //查看电脑上所有的node版本
第二章 Node.js基础知识
2.1 web应用和第一个express应用
web应用
ajax,websockt --> 服务器(web应用) --> 缓存/数据库
通过ajax或者其他方法请求web应用获取数据
express框架
express
接收 req,处理 res
是node中的一种web框架
首先需要先安装express
npm install express -S //生产环境下安装express或者使用 npm install //安装所有依赖
const express = require('express'); //是一个express实例const app = express(); //get请求//请求/name接口的时候需要跟个参数。例:/name/123//返回 {name:tom,age:123}app.get('/name/:age',(req,res)=>{ let {age} = req.params; res.json({ name:'tom', age })}) //post请求app.post('/name',(req,res)=>{ res.send('tom post')}) //所有请求app.all('/name',(req,res)=>{ res.send('tom all methods')}) app.listen(3000,()=>{ console.log('server 启动成功')})
2.2 Route介绍和使用
web服务如何处理一个请求?
url --> 网络 --> dns解析 --> 目标服务器
如何响应这个请求 --> 路由//规则
1. 请求方法来区分
- get --> 响应
- post --> 响应
2.通过uri --> 路径区分(域名后面的路径)
www.baidu.com/a/b/c.html
2.3 express路由演示
路由的区分实例
请求方法区分
app.get('/demo',(req,res)=>{ //req:请求对象 //res:服务器响应对象 res.json({ message:'hello express route from get demo' })})app.post('/demo',(req,res)=>{ //req:请求对象 //res:服务器响应对象 res.json({ message:'hello express route from post demo' })})
uri 区分
app.get('/user/byname',(req,res)=>{ let {name} = req.query; res.json({ name })})app.get('/user/byid',(req,res)=>{ let {id} = req.query; res.json({ id })})
2.4 express路由API使用(一)
1:需要定义一个api/路由,需要满足客户端无论使用什么请求方式都可以得到响应
app.all('/demo',(req,res)=>{ res.json({ message:'demo', method:req.method })})
2:无论客户端使用任何的uri,我们的服务器都可以响应--> 日志
app.all('*',(req,res)=>{ res.json({ message:'demo', method:req.method, uri:req.path })})
2.5 express路由API使用(二)
app.use --> 使用中间件(可以用来写路由,但是尽量写中间件,因为路由也属于中间件)
app.use('/demo',(req,res)=>{ res.json({ message:'demo', method:req.method })})
app.use('/demo',(req,res)=>{ res.json({ message:'demo', method:req.method, uri:req.path })})
2.6 路由拆分
member
sku
order
这三个路由都有一个子路由list
- 定义一个文件
member.router.js
2. 在该文件中写入所要处理的子路由(包括express框架)
和app中的路由写法一致router.[method] //get post ...router.allrouter.use const router = express.Router(); //引入路由router.get('/list',(req,res)=>{ res.json({ { id:001, name:'张三' } })})module.exports = router; //将该路由暴露出去
3. 进入入口文件(app.js)注册路由
const memberRouter = require('./member.router'); //引入刚才写好的member路由文件const skuRouter = require('./sku.router'); //引入刚才写好的sku路由文件//注册路由app.use('/member',memberRouter) // /member作为父级app.use('/sku',memberRouter) // /sku作为父级
2.7 中间件
什么是express中间件
- 是一个函数
- 有四个参数(err,req,res,next),next是个回调
function demo_middleware(err,req,res,next){ //1. 异常 //2. 处理业务功能,然后转交控制权--next //3. 处理响应--结束响应-->当作路由的处理函数}
app.all('*',valid_name_middleware) //当调这个接口的时候,会先进入到all方法,然后执行中间件//判断是否有name参数,如果没有则执行中间件中返回的东西//如果有则进入next回调,执行该执行的东西app.get('/test',(req,res)=>{ res.json({ message:'test' })}) //中间件,检验是否有name参数function valid_name_middleware(req,res,next){ let {name} = req.query; if(!name || !name.length){ res.json({ message:'缺少name参数' }) }else{ next(); }}
内置中间件和第三方中间件介绍
使用方式:
- app级别
-
注册的时候,一定在最顶级
-
app.use --> api去加载进来
function log_middleware(req,res,next){ console.log('请求来了。。。'); next();}app.use(log_middleware); //注册app级别的中间件 //加载一个static的中间件(内置的),会去访问static下面的html文件app.use(express.static('static',{ extensions:['html','htm']}))
2.router级别
//1- 第一个场景router.use(function(req,res,next){ console.log('log from router'); next();})//2- 路由内部使用function vlaid_login_params(req,res,next){ let {name,password} = req.query; if(!name || !password){ res.json({ message:'参数校验失败' }) }else{ req.formdata = { name, password } next(); }}router.get('/login',[/** middleware */],(req,res)=>{ let {formdata} = req; res.json({ message:'login' })})
3.异常处理-->app级别-->router级别
自定义中间件
2.8 异常处理
异常捕获
express内置异常处理
自定义异常处理
app.get('/demo',(req,res)=>{ throw new Error('测试异常功能')}) function demo_middleware(req,res,next){ try{ // mysql操作 }catch(error){ next(error); } //Promise.then().catch(next) //将异常抛到最终的异常处理器上 //异常处理一定是收口的} //异常处理function error_handler_middleware(err,req,res,next){ if(err){ let {message} = err; req.status(500) .json({ message:`${message || '服务器异常'}` }) }}//处理404function not_found_handler(req,res,next){ res.json({ message:'api不存在' })}app.use(not_found_handler)//处理404异常app.use(error_handler_middleware) //异常处理放在最底部
2.9 MySQL
结构化数据库中的一种
是一个服务,提供了数据存放的服务
mysql的安装
2.10 Sequelize介绍和使用
安装sequelize
npm install sequelize -S //生产环境安装npm install sequelize-cli -S //安装scli-equelize-cli提高效率npx sequelize-cli init //初始化sequelize
初始化完成会生成如下文件
config 目录migrations 数据迁移文件modeules ORM里面的每个模块会跟我们的项目关联seeders 初始化脚本
修改config配置文件
"development": { "username": "root",//用户名 "password": null,//密码 "database": "database_development",//数据库名 "host": "127.0.0.1",//主机地址 "dialect": "mysql"//方源 }
npx sequelize-cli model:generate --name User --attributes name:string
完成之后
models目录下会多一个user.js文件
migrations目录下会多一个文件,这个文件就是用来创建表
const models = require('../models/'); //模型对象//models.User //User模型//models.Sequlize //Sequlize类//models.sequlize //sequlize实例 npm install mysql2 -S //安装驱动连接MySQLnpx sequelize-cli db:migrate --env=development //创建表
//创建表中记录app.get('/create',async (req,res)=>{ let {name} = req.query; // promise user --> sequlize对象 let user = await models.User.create({ name }) res.json({ message:'创建成功', user })})//查询表中所有的数据app.get('/list',async (req,res)=>{ let list = await models.User.findAll(); res.json({ list })})////查询表中id为传入id的数据app.get('/detail/:id',async (req,res)=>{ let {id} = req.params; let user = await models.User.findOne({ where:{ id } }) res.json({ user })})
第三章 从实战中熟悉操作
3.1 需求分析
第一步根据用户所提出来的需求进行分析,这一步很重要,分析完成才可以设计你的API
主要分析需要传进来什么参数,实现什么功能
3.2 API设计
- 创建项目目录
- 初始化npm
npm init
3.安装依赖
npm install express mysql2 sequelize supervisor sequelize-cli body-parser -S
4.先把框架写出来
>> app.jsconst express = require('express');const bodyParser = require('body-parser');//post请求需要该中间件const app = express(); app.use(express.json());app.use(express.urlencoded());app.use(bodyParser.urlencoded({extended: true})); app.listen(3000,()=>{ console.log('服务启动成功')})
5.异常处理,所有的错误,http status == 500
app.use((err,req,res,next)=>{ if(err){ res.status(500).json({ message:err.message }) }})
6.API的设计
app.get('/list/:status/:page',async (req,res,next)=>{ res.json({ list:[] })})/*创建一个任务*/app.post('/create',async (req,res,next)=>{ let { name,deadline,content } = req.body; res.json({ todo:{}, name, deadline, content })})/*修改一个任务*/app.post('/update',async (req,res,next)=>{ let { name,deadline,content,id } = req.body; res.json({ todo:{}, name, deadline, content, id })})/*修改一个todo,删除*/app.post('/update_status',async (req,res,next)=>{ let { id,status } = req.body; res.json({ todo:{}, id, status })})
3.3 模型创建
1.数据库的初始化
创建数据库使用`sequelize-cli`初始化项目的数据库配置信息 `npx sequelize init`(建议新建一个目录)生成模型文件 1.migrate 文件 2.model 文件 `npx sequelize model:generate --name Todo --attributes name:string,deadline:date,conten:string`持久化,模型对应的[数据库表] (生成数据库表) `npx sequelize db:migrate`
2.API里面具体使用ORM模型
3.4 API里面具体使用ORM模型
const models = require('../db/models'); //导入模型 /*创建一个todo*/app.post('/create',async (req,res,next)=>{ try{ let { name,deadline,content } = req.body; /**数据持久化到数据库**/ let todo = await models.Todo.create({ name, deadline, content }) res.json({ todo:{}, name, deadline, content }) }catch (error){ next(error); }})/*修改一个todo*/app.post('/update',async (req,res,next)=>{ try{ let { name,deadline,content,id } = req.body; let todo = await models.Todo.findOne({ where:{ id } }); if(todo){ //执行更新功能 todo = await todo.update({ name, deadline, content, id }) } res.json({ todo }) }catch(error){ next(error); }})/*修改一个todo,删除*/app.post('/update_status',async (req,res,next)=>{ try{ let { id,status } = req.body; let todo = await models.Todo.findOne({ where:{ id } }); if(todo && status != todo.status){ //执行更新功能 todo = await todo.update({ status }) } res.json({ todo }) }catch(error){ next(error); }})
3.5 运维和发布
服务要启动在后台,不能在窗口
pm2工具
npm install pm2 -g //全局安装pm2pm2 init //初始化pm2 生成ecosystem.config.js文件ecosystem.config.js文件中apps可以有多个应用
第四章:总结与问题归纳
4.1 总结
1.技术栈 node --> http,异常 web框架,express、hapi、koa、egg 参数校验 mysql的使用,了解 ORM,sequelize使用2.技术关键点 api设计 web-->webserver-->router-->hander-->orm--db3.注意事项 需要做详细的 模型设计-->模型之间的关系 api的使用文档-->api文档的实用工具 测试
4.2 问题归纳
注意:一旦删除了自带的createdAt和updatedAt两个字段,需要做出如下设置
>> models >> user.jsmodule.exports = (sequelize, DataTypes) => { const User = sequelize.define('User', { name: DataTypes.STRING }, { timestamps:false //添加这行代码,改变sequelize的默认字段为false }); User.associate = function(models) { // associations can be defined here }; return User;};
修改字段默认值
>> models >> user.jsconst User = sequelize.define('User', { name: DataTypes.STRING, status:{ type:DataTypes.InTEGER, defaultValue:1 //可以在这里修改默认值 }}, { timestamps:false});
来源:https://www.cnblogs.com/xue-shuai/p/12012650.html