# Node常用框架
# 1、原生http模块
- 服务启动:使用nodemon(本地)、ps2(生产)启动服务器
- nodemon ./http.js,实现热更新,无需重启服务器
- 监听路由:使用pathname进行分支处理
- 获取get请求参数
- 使用url库函数:url(req.url)路径和参数分割,url(req.url, true)路径和参数分割且参数解析
- 获取post请求的参数
- 使用curl发起post请求:curl -v -X POST -d "a=1&b=2" http://localhost:3000
- 使用req的on和end事件获取请求体内容
- 返回:使用res的write事件返回
- 错误处理:监听error事件
const http = require('http')
const url = require('url')
const app = http.createServer(function(req, res) {
//1、获取get请求内容
console.log(req.method, req.url) // req.url是⼀个完整的,⽐如/order?id=4
const { pathname, query } = url.parse(req.url, true) // true的作⽤是解析query字符串为对象
console.log(pathname, query) //输出为/order,query为参数对象{id: 4}
//2、获取post请求内容,即请求体内容
// req 是⼀个可读流,有 data 和 end事件来获取请求体
const requestDataArr = []
req.on('data', function(chunk /* Buffer */) {
requestDataArr.push(chunk) // ⼀条请求体
})
// ⽆论是否有请求体,都会执⾏end事件;express中可以使⽤中间件来获取请求体
req.on('end', function(){
const requestDataBuffer = Buffer.concat(requestDataArr) // 拿到最终的请求体
// 请求已处理完成,res.end参数只能是字符串或者Buffer
res.end(`请求处理完毕${requestDataBuffer.toString()}\n`)
})
// 3、模拟⼀个路由; express⾃带路由系统
if(pathname === '/') {
// ⾸⻚的逻辑
} else if (pathname === '/user') {
// ⽤户中⼼的逻辑
} else {
// 404
}
//4、返回:res是⼀个可写流,有write和end⽅法
res.setHeader('Content-Type', 'text/html;charset=utf-8') //避免中文出现乱码
res.write('已收到请求\n')
res.end(pathname)
})
app.listen(3000, () => {
console.log('raw server starting at port 3000')
})
//错误处理
app.on('error', (err) => {
console.log(err)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 2、express框架
# 1、路由
使用路由中间件app.get、app.post
- res:send方法返回
- req:query属性或者请求参数、params属性获取请求路径的参数
# 2、中间件
- 使用:app.use
- 请求体解析:使用bodyParse中间件,给req添加body对象
- 静态资源中间件:app.use("/static", express.static(__dirname + '/public')),自带
- cookie处理:cookie-parser中间件,给req和res添加cookie对象
- 路由中间件:自带,app.use('/user', (req, res, next) => {})
- 以/user开头
- next表示执行下一个中间件
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser')
//2、中间件
app.use("/static", express.static(__dirname + '/public'));
// 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded());
app.use(cookieParser());
// ⽐如访问/user 开头的⻚⾯需要鉴权
app.use('/user', (req, res, next) => {
console.log('todo 访问/user⻚⾯需要验证身份')
if(req.query.id){
next() //继续执行下一个中间件
}else{
next(new Error('鉴权失败'))
}
})
//错误处理中间件
app.use('/user', (err, req, res, next) => {
console.log('todo 访问/user⻚⾯需要验证身份')
res.send(err.message)
})
//1、路由
app.get('/', (req, res) => {
res.send('⾸⻚')
})
app.get('/user/:userId', (req, res) => {
console.log(req.query, req.params)
res.send('⽤户⻚')
})
app.post('/user', (req, res) => {
console.log(req.body)
console.log('cookie: ', req.headers.cookie, req.cookies)
res.cookie('age', '5')
res.send('⽤户⻚post\n')
})
app.listen(3001, () => {
console.log(`express-server started at 3001`)
})
app.on('error', function(err){
consolg.log('error: ', err)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
- 中间件执行流程和原理
- 洋葱模型
- 异步模式:即使下一个中间件有异步处理,当前中间件不会等待下一个中间件处理完成
//正常函数执行
function a () {
console.log('1-1')
b()
console.log('1-2')
}
function b () {
console.log('2-1')
c()
console.log('2-2')
}
function c () {
console.log('3-1')
console.log('3-2')
}
a() //1-1 2-1 3-1 3-2 2-2 1-2
// 路由中间件
app.get('/test', (req, res, next) => {
console.log('1-1')
next()
console.log('1-2')
}, (req, res, next) => {
console.log('2-1')
next()
console.log('2-2')
}, (req, res, next) => {
console.log('3-1')
next()
console.log('3-2')
})
app.get('/test', (req, res) => {
console.log('test')
res.send('end')
})
//1-1 2-1 3-1 test 3-2 2-2 1-2
app.get('/test', (req, res, next) => {
console.log('1-1')
next()
console.log('1-2')
}, (req, res, next) => {
console.log('2-1')
next()
console.log('2-2')
}, (req, res, next) => {
console.log('3-1')
await sleep(3)
//后面函数会延迟执行
next()
console.log('3-2')
})
app.get('/test', (req, res) => {
console.log('test')
res.send('end')
})
//1-1 2-1 3-1 2-2 1-2 test 3-2
app.get('/test', (req, res, next) => {
console.log('1-1')
next()
console.log('1-2')
}, async (req, res, next) => {//即使下一个中间件有异步处理,当前中间件不会等待下一个中间件处理完成
console.log('2-1')
await next() //不会等待中间件的异步执行完成 Promise.resolve().then(()=> console.log('2-2'))
console.log('2-2')
}, (req, res, next) => {
console.log('3-1')
await sleep(3)
//后面函数会延迟执行
next()
console.log('3-2')
})
app.get('/test', (req, res) => {
console.log('test')
res.send('end')
})
//1-1 2-1 3-1 1-2 2-2 test 3-2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 3、next实现
内部中间件:参考/express/lib/router/route.js Route.prototype.dispatch方法
外部中间件:参考/express/lib/router/index.js proto.handle⽅法
// 模型抽象: [ [a, b, c], [d] ] a -> b -> c -> d
// 1、一维数组模式:内部中间件
// 先实现内部: [a, b, c],先⼿动执⾏a(),a中调⽤next()执⾏b,b中调⽤next()执⾏c
const handlers = [
function a (next) {
console.log('1-1')
next()
console.log('1-2')
},
function b (next) {
console.log('2-1')
next()
console.log('2-2')
},
function c (next) {
console.log('3-1')
console.log('3-2')
}
]
function innerProcess() {
let idx = 0;
function next() {
if(idx >= handlers.length) return;
handlers[idx++](next) // 执⾏a() i = 1; 执⾏b() i = 2; 执⾏c() i = 3;
}
next() // idx = 0
}
innerProcess()
// 2、二维数组形式:外部中间件
// 模型抽象: [ [a, b, c], [d] ] a -> b -> c -> d
const handlers = [
[
function a (next) {
console.log('1-1')
next()
console.log('1-2')
},
function b (next) {
console.log('2-1')
next()
console.log('2-2')
},
function c (next) {
console.log('3-1')
next()
console.log('3-2')
}
],
[
function d (next) {
console.log('4')
}
]
]
function innerProcess(innerHandlers, out) {
let idx = 0;
function next() {
if(idx >= innerHandlers.length) return out(); // 执⾏外部的函数,将使⽤权返还 c -> d
innerHandlers[idx++](next) // 执⾏a() i = 1; 执⾏b() i = 2; 执⾏c() i = 3;
}
next() // idx = 0
}
function outerProcess() {
let idx = 0;
function next() {
if(idx >= handlers.length) return;
//将二维数组中的每个数组对象传入innerProcess执行,执行结束执行next继续传入下一个数组对象
innerProcess(handlers[idx++], next)
}
next()
}
outerProcess()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 4、子路由
使用:require('express').Router()
app.use('/api', apiHandler) //api开头前缀
//apiHandler.js
const router = require('express').Router()
router.post('/news', (req, res) => {
res.send(req.path) //这里的path为/news
})
router.get('/list', (req, res) => {
res.send(req.path)
})
module.exports = router
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 5、错误处理
错误处理是在⼀个特殊签名的中间件中完成的,⼀般被添加到链的最后
- 可以通过next传递错误
- 可以是代码运⾏错误
- 使用最后的中间件捕获
// 可以通过next传递错误
app.get('/test', (req, res, next) => {
console.log('test')
next(new Error('500 can only greet "world"'))
// res.send('end')
})
// 可以是代码运⾏错误
app.use((req, res) => {
if (req.query.greet !== 'world') {
throw new Error('can only greet "world"')
}
res.status(200)
res.send(`Hello ${req.query.greet} from Express`)
})
// 会被最后的中间件捕获,4个参数即可不必放置在最后
app.use((err, req, res, next) => {
if (!err) {
next()
return
}
console.log('Error handler:', err.message)
res.status(500)
res.send('Uh-oh: ' + err.message)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3、Koa框架
# 1、基本用法
- 需先建对象与express不同:const app = new Koa()
- ctx(context)封装了res和req
- 返回使用ctx.body,可使用async和await
- ctx.body最终会转换为res.end
- 执行时机:洋葱模型的最外层,第一个中间件promise有结果后,将ctx.body转换为res.end()
- 异步使用时,不可放置异步函数中,需放置在await的promise中
- 也可直接使用ctx.res和ctx.req
- 常用属性:req、res、request、response
- 返回使用ctx.body,可使用async和await
- ctx属性:
const Koa = require('koa') // ⼀个类
const app = new Koa()
// 中间件,可以使⽤async await
app.use(async function(ctx){
// throw new Error('出错了')
// ctx封装了req和res的功能,这⾥相当于res.end
// 1、有输出,ctx.body在promise结果后
ctx.body = await Promise.resolve('zhuwa')
// 2、无输出
setTimeout(()=>{
ctx.body = 'zhuwa'
}, 3000)
})
// 错误事件
app.on('error', function(err, ctx) {
console.log(err)
ctx.res.end(`500 错误`)
})
app.listen(3002, () => {
console.log('koa server started at 3002')
})
// req request res response的区别
app.use(async function(ctx){
console.log(ctx.req.path) // 原⽣的req
console.log(ctx.request.path) // koa封装的request
console.log(ctx.request.req.path)
console.log(ctx.path) // 代理到request
ctx.body = await Promise.resolve('zhuwa') // ctx封装了req和res的功能,这⾥相当于res.end
//ctx.throw(401, "err msg");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 2、中间件
使用app.use,回调函数只能传一个,多个需多次注册
异步流程会等待后续中间件有结果时返回
app.use(async function(ctx, next) {
console.log('1-1')
await next()
console.log('1-2')
})
app.use(async function(ctx, next) {
console.log('2-1')
await next()
console.log('2-2')
})
app.use(async function(ctx, next) {
console.log('3-1')
await next()
console.log('3-2')
})
//输出:1-1、2-1、3-1、3-2、2-2、1-2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 手写koa-compose
核心代码参考:koa-compose/index.js
/**
* 函数:compose
* @params middleware: Function[]
* @return function fnCompose
*
* 函数:fnCompose
* 作用:执⾏第0个,并传⼊ctx和⼀个next函数,让第0个⾃⼰决定何时执⾏第1个
* @params ctx next函数
* @return promise
* function fnCompose(ctx, next){ return promise }
*
* 函数:next
* 作用:执⾏第i个中间件,并⽤promise包裹起来
* @params i表示执⾏第⼏个
* @return 返回promise
* function next (i) {
* // 执⾏当前的fn,将ctx, next传⼊(绑定下⼀个i, i + 1)
* return promise
* }
*/
/**
* 注意的细节:边界情况处理
* 1、middleware必须是数组,其中每⼀项必须是fuction
* 2、最后⼀个中间件调⽤了next,i === length
* 3、⼀个中间件多次调⽤next会报错
* 异常捕获
*/
const handlers = [
async function(ctx, next) {
console.log('1-1')
await next()
console.log('1-2')
},
async function(ctx, next) {
console.log('2-1')
await next()
console.log('2-2')
},
async function(ctx, next) {
console.log('3-1')
await sleep(3)
console.log('3-2')
}
]
const compose = function(middleware) {
let index = -1 //next只能调用一次方法
return function(ctx, next) {
function disptach(i) {
if(index >= i) return Promise.reject('next multiples callback')
index = i
const fn = middleware[i]
if(i === middleware.length) fn = next
if(!fn) return Promise.resolve()
try {
return Promise.resolve(fn(ctx, disptach.bind(null, i + 1)))
} catch (err) {
return Promise.reject(err)
}
}
return disptach(0)
}
}
const fnCompose = compose(handlers)
const context = {}
fnCompose(context).then(()=>{
console.log('通过ctx.body 设置 res.end')
}).catch(err => {
console.log('err', err)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 3、与express比较
框架 | express | koa |
---|---|---|
模型 | 线性模型 | 洋葱模型 |
表现 | 同步表现为洋葱模型,但遇到异步,即使使⽤了 await next()也不会等待,会继续向下执⾏,因为next()返回undefined | ⽆论同步,还是异步,都是洋葱模型,可以使⽤ await和next() 来等待下⼀个中间件执⾏完成 |
原理 | 使⽤回调, next(),返回undefined | next(),返回promise,会把中间件⽤promise包裹起来 |
错误 | 错误处理是在⼀个特殊签名的中间件中完成的,它必须被添加到链的后⾯才能捕获到前⾯的错误 | 可以使⽤try catch 捕获中间件错误 |
注意 | await next() 也不会等待下⼀个中间件异步完成 | 要使⽤await来等待异步操作;注意res.end的时机,等最外层的中间件(也就是第⼀个中间件)的promise有结果后,响应就会被返回 ctx.body ->res.end(ctx.body) |
# 4、中间件编写
//编写⼀个计算请求的时⻓的中间件
// koa 中间件
app.use(async function(ctx, next) {
console.time('serviceTime')
await next()
console.timeEnd('serviceTime')
})
// express 中间件
app.use(function(req, res, next) {
console.time('service')
next()
res.once('close', () => {
console.timeEnd('service')
});
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5、错误处理
// 可以使⽤try catch 捕获中间件错误
// 在最顶层捕获未处理的错误
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
const status = err.status || 500;
ctx.status = status;
ctx.type = "html";
ctx.body = `
<b>${status}</b> ${err}
`;
// emmit
ctx.app.emit("error", err, ctx);
}
});
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = 400
ctx.body = `Uh-oh: ${err.message}`
console.log('Error handler:', err.message)
}
})
app.use(async (ctx) => {
if (ctx.query.greet !== 'world') {
throw new Error('can only greet "world"')
}
console.log('Sending response')
ctx.status = 200
ctx.body = `Hello ${ctx.query.greet} from Koa`
})
// 也可以使⽤总的错误事件来统⼀处理
// 错误事件
app.on('error', function(err) {
console.log(err)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 6、常用中间件
- koa-router:路由
- koa-static:静态资源
- koa-mounut:子路由
- koa-body:body解析
- koa-parameter:参数校验
//1、koa-router
const KoaRouter = require('koa-router')
router.get('/page', async ctx => {
ctx.body = await new Promise((resolve, reject) => {
resolve('ok')
})
})
// 注册中间件
app.use(router.routes())
// 添加前缀
const router = new Router({ prefix: '/user' })
// 重定向
router.get('/home', async ctx => {
ctx.redirect('http://baidu.com');
});
// 路由参数
router.get('/:id', async ctx => {
ctx.body = {
msg: 'index page',
params: ctx.params.id // 通过 ctx.params.id 获取到的是 1
};
});
router.get('/', async ctx => {
ctx.body = {
msg: 'index page',
query: ctx.query // ctx.query会获取url后⾯携带的参数对象
};
});
// allowedMethod
// 如果没有这⼀⾏, 当使⽤其他请求⽅式请求user时, 会提示404
// 如果有这⼀⾏, 当使⽤其他请求⽅式请求user时, 提示405 method not allowed
app.use(router.allowedMethod());
//2、koa-static
const KoaStatic = require('koa-static')
app.use(KoaStatic(path.resolve(__dirname, '../dist/assets')))
//3、koa-mounut
const KoaMount = require('koa-mount')
// 添加前缀
app.use(KoaMount('/assets', KoaStatic(path.resolve(__dirname, '../dist/assets'))))
//4、koa-body
const bodyparser = require('koa-body');
// 在注册此中间件之后, 会在 ctx 上下⽂注⼊ ctx.request.body 属性 ⽤于获取客户端传递来的数据
app.use(bodyparser());
router.post('/', async ctx => {
ctx.body = {
code: 200,
//body 可以获取form表单数据, json数据
msg: ctx.request.body
}
})
//5、koa-parameter
const parameter = require('koa-parameter');
parameter(app);
router.post('/', async ctx => {
//接收⼀个对象
ctx.verifyParams({
// 校验的简写形式
username: 'string',
password: { type: 'string', required: true } // 或者也可以这样
})
ctx.body = { code: 1 }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 4、Sequalize
orm框架(对象关系映射)
# 1、安装
npm install --save sequelize
# 根据具体使⽤的数据库选择安装以下某个包
npm install --save pg pg-hstore # Postgres
npm install --save mysql2
npm install --save mariadb
npm install --save sqlite3
npm install --save tedious # Microsoft SQL Server
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2、连接数据库
// 配置数据库连接
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: path.join(__dirname, '../database.sqlite')
});
// 连接数据库
const connectDatabase = async () => {
try {
await sequelize.authenticate();
console.log('数据库连接成功');
} catch (error) {
console.error('数据库连接失败:', error);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3、model
作⽤:⽤来描述数据库表的结构
const User = sequelize.define('User', {
// Model attributes
id: {
type: DataTypes.INTEGER(11),
primaryKey: true, // 主键
autoIncrement: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
// allowNull 默认为 true
},
age: {
type: DataTypes.INTEGER
}
}, {
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 4、增删改查
// 1、增加
// service
async function addUser(User, userInfo) {
console.log('addUser', User, userInfo)
const user = await User.create(userInfo);
return user
}
// controler
app.post('/user', async (req, res) => {
const result = await services.User.addUser(req.body)
res.send(result)
})
//2、改
// service
function updateUser(User, id, userInfo) {
console.log('updateUser', User, userInfo)
return User.update(
{
...userInfo,
},
{
where: {
id, //查询条件
}
}
)
}
// controller
app.put('/user/:id', async (req, res) => {
// console.log(req.params.id)
const result = await services.User.updateUser(req.params.id, req.body)
res.send(result)
})
//3、查找
function getAllUsers(User) {
return User.findAll(
// {
// attributes: ['id', 'firstName', 'lastName']
// }
)
}
function getUserById(User, id) {
// return User.findOne({
// where: {
// id,
// }
// });
return User.findByPk(id)
}
// 获取列表
app.get('/user', async (req, res) => {
const result = await services.User.getAllUsers({})
res.send(result)
})
// 获取⼀个
app.get('/user/:id', async (req, res) => {
const userId = req.params.id
if(!userId) {
res.send('error id not found')
return;
}
const result = await services.User.getUserById(userId)
res.send(result)
})
//4、删除
async function deleteUserById(User, id) {
try {
const result = await User.destroy({
where: { //where是指定查询条件
id,
}
})
return result
} catch (e) {
return Promise.reject(e)
}
}
// 删除
app.delete('/user/:id', async (req, res) => {
try {
const result = await services.User.deleteUserById(req.params.id)
if(result === 1) {
res.send('delete success')
} else {
res.send('delete fail')
}
} catch(e) {
res.send(e)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93