koa简单使用

一. RESTful(Representational State Transfer)风格API:

1. 客服服务端(Client-Server)

关注点分离,服务端专注数据存储,提升了简单性,前端专注用户界面,提升了可移植性

2. 无状态(Stateless)

每次请求必须包括所有信息,不能依赖上下文信息,客户端保留所有会话信息,服务端不再保留会话信息

3. 缓存(Cache)

所有信息必须标记为可缓存或不可缓存

4. 统一接口(Uniform Interface)

接口设计尽可能统一,接口与实现解耦

5. 分层系统(Layered System)

每一层只知道相邻的一层,每一层负责不同的功能安全,负载均衡

6. 按需代码

RESTful风格最佳例子:https://developer.github.com/v3/

二.koa基础使用

1.自定义路由

koa所需工具:nodemon自动重启
记得取package.json里写脚本:"start":"nodemon index.js",
断点调试和查看官网的api:ctx.url ctx.status ctx.method ctx.body

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

app.use(async (ctx) => {
    if (ctx.url === '/') {
        //处理不同的url
        ctx.body = "这是主页 "
    } else if (ctx.url === "/user") {
        //处理不同的方法
        if (ctx.method === "GET") {
            ctx.body = "这是用户列表页"
        } else if (ctx.method === "POST") {
            ctx.body = "创建用户"
        } else {
            //方法不允许
            ctx.status = 405
        }

    } else if (ctx.url.match(/\/user\/\w+/)) {
        // 解析请求参数
        const userId = ctx.url.match(/\/user\/(\w+)/)[1]
        ctx.body = `这是用户${userId}`
    } else {
        ctx.status = 404
    }
})
app.listen(3000)
2.使用koa-router,不用自定义路由

koa-router实现路由

获取HTTP请求参数:

  1. 获取query(ctx.query). ?q=keyword
  2. 获取body(koa-bodyparser||koa-body)
  3. 获取header(ctx.header). Accept,Cookie
  4. 获取router params(ctx.params). /users/:id

发送HTTP响应:

  1. 发送status(ctx.status)
  2. 发送body(ctx.body)
  3. 发送header(ctx.set("Allow","get","post"))Allow Content-type
  4. 实现用户的增删改查(get获取用户,post新建返回新建用户,put全部更新,patch局部更新,delete删除返回204,options显示支持什么访问方法)
    常用状态码:
    204:删除用户后返回,表示成功状态响应代码指示请求已成功,但没有内容返回
    200:响应成功,内容返回
    500:运行时错误
    404:找不到
    412:先决条件失败
    422:无法处理的实体,参数格式不对
const Koa = require("koa")
const Router = require("koa-router")
const app = new Koa()
const router = new Router()
//前缀
const userRouter = new Router({ prefix: "/user" })
const koaBody = require("koa-body")
const parser = require("koa-bodyparser")
//多中间件  
const auth = async (ctx, next) => {
    // if(ctx.url !== "/user"){
    //     //没有权限  
    //     ctx.throw(401)
    // }
    await next( )
}

router.get("/", (ctx) => {
    ctx.body = "这是主页"
})
//处理不同的url
userRouter.get('/', auth, (ctx) => {
    ctx.body = "这是用户列表"
})
//处理不同的方法 post新建用户 返回新建的用户
userRouter.post("/", auth, (ctx) => {
    ctx.body = "创建用户"
})
//解析请求参数 get查列表 返回列表
userRouter.get("/:id", auth, (ctx) => {
    //设置header响应头
    ctx.set("Allow","GET,POST")
    ctx.body = `这是用户${ctx.params.id}列表 `
})
//put修改 返回修改的用户
userRouter.put("/:id", (ctx) => {
    ctx.body = `这是用户${ctx.params.id}`
})
//delete删除 返回实体,但是成功
userRouter.delete("/:id", (ctx) => {
    ctx.status = 204
})

//注册中间件
app.use(parser( ))
app.use(router.routes())
app.use(userRouter.routes())
//响应options方法请求,告诉他所支持的请求方法
//405方法不允许,支持但没写。501方法无法实现,不存在 
app.use(userRouter.allowedMethods())

app.listen(3000)
//http请求参数:
//Query String  如?q=keyword(可选)
//Router Params 如/user/:id(必传)
//Body,如json,form等conten-type里面会写到
//Header,如accept,cookie,jwt等
  
//发送http响应:
//发送status。如200/400等
//发送body,如json等
//发送header,如allow,content-type等 
//1.每个资源的控制器尽量发在不同的文件里
//2.尽量使用类+类的形式编写控制器
//3.严谨的错误处理
3.错误处理和更加合理的目录结构

错误处理:
ctx.throw(422,'文本信息')
koa-json-error:记得隐藏堆栈信息,在生产环境的时候
koa-parameter:校验参数ctx.verifyParams({name:{type:"string",required:true}})

const Koa = require("koa")
const bodyParser = require("koa-bodyparser")
const app = new Koa()
const routing = require("./routes")
const error = require("koa-json-error")
const parameter = require('koa-parameter')//校验参数

//自定义的错误处理,无法捕获404信息
// app.use(async (ctx, next) => {
//     try {
//         await next()
//     } catch (error) {
//         //断点
//         ctx.status = error.status || error.statusCode || 500
//         //返回json格式
//         ctx.body = {
//             message: error.message
//         }
//     }
// })
app.use(error({
    //定制返回格式
    postFormat: (e, { stack, ...rest }) => {//原生的error,应该返回的格式
        // "start": "export NODE_ENV='production'&& nodemon app",
        return process.env.NODE_ENV === "production" ? rest : { stack, ...rest }
    }
}))//koa-json-error中间价处理错误,404,412,500
app.use(bodyParser())//解析请求体
app.use(parameter(app))//校验参数,传入app,进行全局的使用,全局方法,比如在create方法中
routing(app)
app.listen(3000, () => { console.log("程序在3000端口启动了") })
//异常状况有哪些
//1.运行是错误,服务器内部的错误500
//2.逻辑错误,找不到404,先决条件失败412,无法处理的实体(参数格式不对422)
// 为什么要使用错误处理
//1.防止程序挂掉
//2.告诉用户信息
//3.便于开发者调试
目录结构
4.链接数据库的操作

到这里为止的仓库地址:https://github.com/ranzhouhang/2020-9-12practice

你可能感兴趣的:(koa简单使用)