Koa2简明笔记

起步

安装

$ npm init -y
$ npm install koa

第一个程序

新建 index.js 文件

const Koa = require('koa')
const app = new Koa()

app.use(async ctx => {
  ctx.body = 'Hello World'
})

app.listen(3000)

启动

$ node index.js

开发环境可以使用 nodemon 来进行热更新

$ npm install nodemon -D

修改 package.json 文件,添加 "dev": "nodemon index.js"

{
  "name": "koa-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
+   "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "koa": "^2.13.4"
  },
  "devDependencies": {
    "nodemon": "^2.0.20"
	}
}

此时使用 npm run dev 来运行我们的开发环境

路由

安装 koa-router

$ npm install @koa/router

修改 index.js 文件

const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()

router.get('/test', ctx => {
  ctx.body = 'test page'
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

重新执行 node index.js 或者等待 nodemon 热加载完毕

访问 http://localhost:3000/test,此时可以看到页面输出内容 test page

获取请求数据

获取GET请求数据

  • query 形式传参,通过 ctx.request.query 获取参数(request可省略),形如 ?xxx=xxx&xxx=xxx
router.get('/test', ctx => {
  const query = ctx.request.query
  ctx.body = {
    query
  }
})

访问 http://localhost:3000/test?name=zs&age=22,输出:

{
  "query": {
    "name": "zs",
    "age": "22"
  }
}
  • params 形式传参,通过 ctx.request.params 获取参数(request可省略),形如 /users/xxx
router.get('/users/:id', ctx => {
  const params = ctx.request.params
  ctx.body = {
    params
  }
})

访问 http://localhost:3000/users/1,输出:

{
  "params": {
    "id": "1"
  }
}

获取POST请求数据

使用 koa-body 中间件

安装

$ npm install koa-body

index.js 文件中

const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()
+ const koaBody = require('koa-body')

+ app.use(koaBody())

router.post('/', ctx => {
  const body = ctx.request.body
  ctx.body = {
    body
  }
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

使用 ctx.request.body 接收 post 传参

可以使用 postman 、apifox 等 api 调试工具进行测试,或者使用 jetbrains 开发工具的 .http 文件进行测试

在这里插入图片描述

此时返回响应

{
  "body": {
    "id": 999,
    "value": "content"
  }
}

静态资源

安装 koa-static

$ npm install koa-static

根目录新建 assets/index.css 文件,写入

#app {
    background-color: #ccc;
}

index.js 文件中

const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()
const koaBody = require('koa-body')
+ const koaStatic = require('koa-static')
+ const path = require('path')

app.use(koaBody())
+ app.use(koaStatic(path.resolve(__dirname, 'assets')))

router.get('/', ctx => {
    ctx.body = '111'
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

访问 http://localhost:3000/index.css

文件上传

const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()
const {koaBody} = require('koa-body')
const koaStatic = require('koa-static')
const path = require('path')

app.use(koaBody())
+ app.use(koaStatic(path.resolve(__dirname, 'upload')))


router.post('/upload', koaBody({
    multipart: true,
    formidable: {
        uploadDir: path.resolve(__dirname, 'upload'),
        keepExtensions: true,
    }
}), ctx => {
    const {file} = ctx.request.files
    ctx.body = {
        url: `${ctx.origin}/${file.newFilename}`
    }
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

postman 测试

浏览器打开 http://localhost:3000/6a70c105d00700018d83b5203.jpg 即可访问图片

模板引擎

art-template

安装 art-template

$ npm install art-template koa-art-template

使用

新建 view/index.art 文件

<!doctype html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <h1>{{ title }}</h1>
</body>
</html>

index.js 文件

const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()
const render = require('koa-art-template')

render(app, {
  root: path.join(__dirname, 'view'),
  extname: '.art',
  debug: process.env.NODE_ENV !== 'production'
})

router.get('/', ctx => {
  ctx.render('index', {
    title: 'hello art-template'
  })
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

更多语法参考 https://aui.github.io/art-template/zh-cn/docs/index.html

错误处理

使用 koa-onerror 对错误进行处理,返回 json 格式

安装

$ npm install koa-onerror

使用

const Koa = require('koa')
const app = new Koa()
const onerror = require('koa-onerror')

// 404 Not Found
app.use(async (ctx, next) => {
    await next()
    if (ctx.status === 404) {
        ctx.throw(404)
    }
})

// error handler
onerror(app, {
    accepts() {
        return 'json'
    },
    json(err, ctx) {
        ctx.body = {
            code: ctx.status || 500,
            msg: err.message
        }
    }
})

使用 ctx.throw([status], [msg], [properties]) 抛出异常,如:ctx.throw(401, 'id is required')

数据库

koa2 中常使用 orm 框架来操作数据库,其中最常见的两个框架为 mongoosesequelize ,分别对应 MongoDB 数据库和 MySQL 数据库。此外,sequelize 还支持 MariaDB,SQLite 和 PostgreSQL 数据库

mongoose

安装
$ npm install mongoose
连接
const mongoose = require('mongoose')

mongoose.connect('mongodb://username:password@host/database', {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log('数据库连接成功')
}).catch(error => {
  console.log(error)
  console.log('数据库连接失败')
})
创建一个模型
const mongoose = require('mongoose')

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  email: String,
  avatar: String
})
const User = mongoose.model('User', userSchema)
增删改查
router.post('/users', async ctx => {
  const { username, password } = ctx.request.body
  const user = await User.create({ username, password })
  ctx.body = {
    user
  }
})

请求

POST http://localhost:3000/users
Content-Type: application/json

{
  "username": "admin",
  "password": "123456"
}

响应

{
  "user": {
    "username": "admin",
    "password": "123456",
    "_id": "6352c002f55b91e7f9187c6f",
    "__v": 0
  }
}
router.put('/users', async ctx => {
  const { id } = ctx.query
  const { username, password } = ctx.request.body
  const user = await User.findByIdAndUpdate(id, { username, password }, { new: true })
  ctx.body = {
    user
  }
})

请求

PUT http://localhost:3000/users?id=6352c002f55b91e7f9187c6f
Content-Type: application/json

{
  "username": "admin1",
  "password": "123456789"
}

响应

{
  "user": {
    "_id": "6352c002f55b91e7f9187c6f",
    "username": "admin1",
    "password": "123456789",
    "__v": 0
  }
}
router.delete('/users', async ctx => {
  const { id } = ctx.query
  const { username, password } = ctx.request.body
  const user = await User.findByIdAndDelete(id, { username, password }, { new: true })
  ctx.body = {
    user
  }
})

请求

DELETE http://localhost:3000/users?id=6352c002f55b91e7f9187c6f

响应

{
  "user": {
    "_id": "6352c002f55b91e7f9187c6f",
    "username": "admin1",
    "password": "123456789",
    "__v": 0
  }
}
router.get('/users',  async ctx => {
  const {id} = ctx.query
  if (!id) {
    const users = await User.find()
    ctx.body = {
      users
    }
  } else {
    const user = await User.findById(id)
    ctx.body = {
      user
    }
  }
})

请求1

GET http://localhost:3000/users

响应1

{
  "users": [
    {
      "_id": "6352c35680bd9bce302ad3f2",
      "username": "admin",
      "password": "123456",
      "__v": 0
    }
  ]
}

请求2

GET http://localhost:3000/users?id=6352c35680bd9bce302ad3f2

响应2

{
  "user": {
    "_id": "6352c35680bd9bce302ad3f2",
    "username": "admin",
    "password": "123456",
    "__v": 0
  }
}
const Koa = require('koa')
const app = new Koa()
const router = require('@koa/router')()
const koaBody = require('koa-body')
const koaStatic = require('koa-static')
const path = require('path')
const render = require('koa-art-template')

const mongoose = require('mongoose')

mongoose.connect('mongodb+srv://root:yuan521jin@oyal.vysd5.mongodb.net/koa-demo?ssl=true&authSource=admin', {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log('数据库连接成功')
}).catch(error => {
  console.log(error)
  console.log('数据库连接失败')
})

app.use(koaBody())
app.use(koaStatic(path.resolve(__dirname, 'assets')))
app.use(koaStatic(path.resolve(__dirname, 'upload')))
render(app, {
  root: path.join(__dirname, 'view'),
  extname: '.art',
  debug: process.env.NODE_ENV !== 'production'
})

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  email: String,
  avatar: String
})

const User = mongoose.model('User', userSchema)

router.get('/users',  async ctx => {
  const {id} = ctx.query
  if (!id) {
    const users = await User.find()
    ctx.body = {
      users
    }
  } else {
    const user = await User.findById(id)
    ctx.body = {
      user
    }
  }
})

router.post('/users', async ctx => {
  const { username, password } = ctx.request.body
  const user = await User.create({ username, password })
  ctx.body = {
    user
  }
})

router.put('/users', async ctx => {
  const { id } = ctx.query
  const { username, password } = ctx.request.body
  const user = await User.findByIdAndUpdate(id, { username, password }, { new: true })
  ctx.body = {
    user
  }
})

router.delete('/users', async ctx => {
  const { id } = ctx.query
  const user = await User.findByIdAndDelete(id)
  ctx.body = {
    user
  }
})


router.post('/upload', koaBody({
  multipart: true,
  formidable: {
    uploadDir: path.resolve(__dirname, 'upload'),
    keepExtensions: true,
  }
}), ctx => {
  const { file } = ctx.request.files
  console.log(file)
  ctx.body = {
    url: `${ctx.origin}/${file.newFilename}`
  }
})

app.use(router.routes()).use(router.allowedMethods())

app.listen(3000)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值