Koa 框架

Koa 框架

认识 Koa

  • 前面我们已经学习了express,另外一个非常流行的Node Web服务器框架就是Koa。
  • Koa官方的介绍:
    • koa:next generation web framework for node.js
    • koa:node.js的下一代web框架;
  • 事实上,koaexpress同一个团队开发的一个新的Web框架:
    • 目前团队的核心开发者TJ的主要精力也在维护Koaexpress已经交给团队维护了;
    • Koa旨在为Web应用程序和API提供更小、更丰富和更强大的能力;
    • 相对于express具有更强的异步处理能力(后续我们再对比);
    • Koa的核心代码只有1600+行,是一个更加轻量级的框架,我们可以根据需要安装和使用中间件;
  • 事实上学习了express之后,学习koa的过程是很简单的;

Koa 初体验

  • 我们来体验一下koaWeb服务器

    • 在桌面新建文件夹learn_koa

    • 打开终端初始化项目npm init -y

    • package.json配置脚本

      {
        "name": "learn_koa",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
          "start": "nodemon ./src/app.js"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "dependencies": {
          "koa": "^2.13.4",
          "nodemon": "^2.0.16"
        }
      }
      
    • 根据脚本新建文件src,在文件src下面新建文件夹app.js

    • 安装koa框架npm i koa

      在这里插入图片描述

    • 启动项目npm start

      在这里插入图片描述

  • koa注册的中间件提供了两个参数:

  • ctx:上下文(Context)对象;

    • koa并没有像express一样,将reqres分开,而是将它们作为ctx的属性;

    • ctx代表依次请求的上下文对象;

    • ctx.request:获取请求对象;

    • ctx.response:获取响应对象;

      const Koa = require("koa");
      
      const app = new Koa();
      
      // context 上下文对象
      // 包含两个主要的对象 request responst
      app.use((context, next) => {
        console.log(context);
        console.log("普通中间件");
      });
      
      app.listen(8888, () => {
        console.log("服务器开启成功");
      });
      

      在这里插入图片描述

  • next:本质上是一个dispatch,类似于之前的next

Koa中间件

  • koa通过创建的app对象,注册中间件只能通过use方法:
    • Koa并没有提供methods的方式来注册中间件;
    • 也没有提供path中间件来匹配路径;
  • 但是真实开发中我们如何将路径和method分离呢?
    • 方式一:根据 request自己来判断;
    • 方式二:使用第三方路由中间件;

路由的使用

  • koa官方并没有给我们提供路由的库,我们可以选择第三方库:koa-router

    • npm install koa-router

      在这里插入图片描述

  • 我们可以先封装一个user.router.js的文件:

    // router/user.js 
    const Router = require("koa-router");
    
    const userRouter = new Router({
      prefix: "/user",
    });
    
    userRouter.get("/", (ctx) => {
      // 响应结果
      ctx.body = "用户列表";
    });
    
    userRouter.post("/", (ctx) => {
      // 响应结果
      ctx.body = "添加成功";
    });
    userRouter.delete("/", (ctx) => {
      // 响应结果
      ctx.body = "删除成功";
    });
    userRouter.patch("/", (ctx) => {
      // 响应结果
      ctx.body = "修改成功";
    });
    
    module.exports.userRouter = userRouter;
    
  • app中将router.routes()注册为中间件:

    const Koa = require("koa");
    
    const { userRouter } = require("./router/user");
    
    const app = new Koa();
    
    // 注册路由中间件
    // userRouter.routes() 加载路由规则
    // userRouter.allowedMethods() 对于没有实现和没有使用的请求方式做出正确的响应
    app.use(userRouter.routes()).use(userRouter.allowedMethods());
    
    app.listen(8888, () => {
      console.log("服务器开启成功");
    });
    
  • 注意:allowedMethods用于判断某一个method是否支持:

    • 如果我们请求 get,那么是正常的请求,因为我们有实现get
    • 如果我们请求 putdeletepatch,那么就自动报错:Method Not Allowed,状态码:405
    • 如果我们请求 linkcopylock,那么就自动报错:Not Implemented,状态码:501

参数解析:params - query

  • 请求地址:localhost:8888/user/2

    • 获取params

      // router/user.js
      
      const Router = require("koa-router");
      
      const userRouter = new Router({
        prefix: "/user",
      });
      
      userRouter.get("/:id", (ctx) => {
        // params 方式传参
        console.log(ctx.params.id);
        // 响应结果
        ctx.body = "用户列表";
      });
      
      module.exports.userRouter = userRouter;
      

      在这里插入图片描述

  • 请求地址:localhost:8888/user?name=张三&age=21

    • 获取query

      // router/user.js
      
      const Router = require("koa-router");
      
      const userRouter = new Router({
        prefix: "/user",
      });
      
      userRouter.get("/", (ctx) => {
        // query 方式传参
        console.log(ctx.query);
        // 响应结果
        ctx.body = "用户列表";
      });
      
      module.exports.userRouter = userRouter;
      

      在这里插入图片描述

参数解析:json

  • 请求地址:http://localhost:8888/user

    • bodyjson格式

      在这里插入图片描述

  • 获取json数据:

  • 安装依赖:npm install koa-bodyparser;

    在这里插入图片描述

  • 使用koa-bodyparser的中间件;

    • 在入口文件index.js

      const Koa = require("koa");
      
      const bodyParser = require("koa-bodyparser");
      
      const { userRouter } = require("./router/user");
      
      const app = new Koa();
      
      // bodyParser() 解析 json 数据的中间件
      app.use(bodyParser());
      
      // 注册路由中间件
      // userRouter.routes() 加载路由规则
      // userRouter.allowedMethods() 对于没有实现和没有使用的请求方式做出正确的响应
      app.use(userRouter.routes()).use(userRouter.allowedMethods());
      
      app.listen(8888, () => {
        console.log("服务器开启成功");
      });
      
    • router文件下面的user.js

      // router/user.js
      
      const Router = require("koa-router");
      
      const userRouter = new Router({
        prefix: "/user",
      });
      
      userRouter.post("/", (ctx) => {
        // json 方式传参
        console.log(ctx.request.body);
        // 响应结果
        ctx.body = "添加成功";
      });
      
      module.exports.userRouter = userRouter;
      

参数解析:x-www-form-urlencoded

  • 请求地址:http://localhost:8888/user

    • bodyx-www-form-urlencoded格式:

      在这里插入图片描述

  • 获取json数据:(和json是一致的)

    • 安装依赖: npm install koa-bodyparser;

    • 使用koa-bodyparser的中间件;

      • 在入口文件index.js

        const Koa = require("koa");
        
        const bodyParser = require("koa-bodyparser");
        
        const { userRouter } = require("./router/user");
        
        const app = new Koa();
        
        // bodyParser() 解析 json 数据的中间件
        app.use(bodyParser());
        
        // 注册路由中间件
        // userRouter.routes() 加载路由规则
        // userRouter.allowedMethods() 对于没有实现和没有使用的请求方式做出正确的响应
        app.use(userRouter.routes()).use(userRouter.allowedMethods());
        
        app.listen(8888, () => {
          console.log("服务器开启成功");
        });
        
      • router文件下面的user.js

        // router/user.js
        
        const Router = require("koa-router");
        
        const userRouter = new Router({
          prefix: "/user",
        });
        
        userRouter.put("/", (ctx) => {
          // json 方式传参
          console.log(ctx.request.body);
          // 响应结果
          ctx.body = "修改成功";
        });
        
        module.exports.userRouter = userRouter;
        

参数解析:form-data

  • 请求地址:http://localhost:8888/user/upload

    • bodyform-data格式

      在这里插入图片描述

  • 解析body中的数据,我们需要使用multer

    • 安装依赖:npm install koa-multer;

      在这里插入图片描述

    • 使用multer中间件;

      // router/user.js
      
      const Router = require("koa-router");
      const multer = require("koa-multer");
      // 注意我这里安装的nanoid是3.x的版本,其它版本可能会报错
      const { nanoid } = require("nanoid");
      const { extname } = require("path");
      
      const userRouter = new Router({
        prefix: "/user",
      });
      
      const storage = multer.diskStorage({
        destination(req, file, cb) {
          cb(null, "uploads/");
        },
        filename(req, file, cb) {
          // 文件名
          const fileName = nanoid();
          // 文件的后缀名
          const extName = extname(file.originalname);
          cb(null, fileName + extName);
        },
      });
      // 文件上传
      const upload = multer({
        storage,
      });
      userRouter.post("/upload", upload.single("file"), (ctx) => {
        // form-data 方式传参
        // 文件信息
        console.log(ctx.req.file);
        // 表单数据
        console.log(ctx.req.body);
        // 响应结果
        ctx.body = "文件上传成功";
      });
      
      module.exports.userRouter = userRouter;
      

      在这里插入图片描述

数据的响应

  • 输出结果:body将响应主体设置为以下之一:

    • string :字符串数据

      ctx.response.body = "hello world";
      
    • BufferBuffer数据

    • Stream :流数据

    • Object|| Array:对象或者数组

      // Object 
      ctx.body = {
        name: "why",
        age: 18,
        height: 1.88,
      };
      
      // Array
      ctx.body = ["abc", "def", "nba"];
      
    • null :不输出任何内容

    • 如果response.status尚未设置,Koa会自动将状态设置为200204

  • 请求状态:status

    ctx.status = 201;
    ctx.response.status = 204;
    

静态服务器

  • koa并没有内置部署相关的功能,所以我们需要使用第三方库:

    • npm install koa-static
      在这里插入图片描述
  • 部署的过程类似于express

    const Koa = require("koa");
    
    const bodyParser = require("koa-bodyparser");
    const static = require("koa-static");
    
    const { userRouter } = require("./router/user");
    
    const app = new Koa();
    
    // bodyParser() 解析 json 数据的中间件
    app.use(bodyParser());
    
    app.use(static("./dist/index.html"));
    
    // 注册路由中间件
    // userRouter.routes() 加载路由规则
    // userRouter.allowedMethods() 对于没有实现和没有使用的请求方式做出正确的响应
    app.use(userRouter.routes()).use(userRouter.allowedMethods());
    
    app.listen(8888, () => {
      console.log("服务器开启成功");
    });
    
    

和express对比

  • 在学习了两个框架之后,我们应该已经可以发现koaexpress的区别:
  • 从架构设计上来说:
    • express是完整和强大的,其中帮助我们内置了非常多好用的功能;
    • koa是简洁和自由的,它只包含最核心的功能,并不会对我们使用其他中间件进行任何的限制。
      • 甚至是在app中连最基本的getpost都没有给我们提供;
      • 我们需要通过自己或者路由来判断请求方式或者其他功能;
  • 因为expresskoa框架他们的核心其实都是中间件:
    • 但是他们的中间件事实上,它们的中间件的执行机制是不同的,特别是针对某个中间件中包含异步操作时;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值