zoukankan      html  css  js  c++  java
  • 在koa中想要优雅的发送响应?看这就对了

    背景
    前不久把项目中用了很久的一个伪中间件撸成了一个npm包发布了出去。

    为什么叫伪中间件?正常的中间件的引用方式, 就拿body-parser为例。
    var Koa = require('koa');
    var bodyParser = require('koa-bodyparser');
    
    var app = new Koa();
    app.use(bodyParser());
    
    app.use(async ctx => {
      // the parsed body will store in ctx.request.body
      // if nothing was parsed, body will be an empty object {}
      ctx.body = ctx.request.body;
    });
    

     反观我撸的伪中间件的引用方式。

    const response = require('../uitls/Response');
    const data = {};
    response.success(ctx, data);
    什么要这么干呢...纯粹是因为这个伪中间件与现有项目的耦合度太高了,
    为(就)了(是)方(懒)便在项目里面把这个伪中间件的引用方式从本地工具组件换成从node_modules里引用。
    例如这样。
    const response = require('koa2-response');
    const data = {};
    response.success(ctx, data);
    经过一番折腾,项目中的引用方式全部替换完了。然后我的学弟就看不下去了。。。提了一个pullrequest给我。把这个着实封装成了一个中间件

    优化

    首先是改变了引用方式,之前的方式是直接导出了一个对象,这个对象有两个方法,分别是success和error。使用这种方式,就必须要在每个controller中都引用一次,如下。
    const response = require('../utils/Response');
    
    优化之后,只需要在node的入口文件中做如下操作就好
    const koa = require('koa');
    const app = new koa();
    const router = require('koa-router')();
    const response = require('koa2-response');
    
    const code = {
      UNKNOWN_ERROR: [1, 'Sorry, you seem to have encountered some unknown errors.']
    }
    
    router
      .get('/', (ctx, next) => {
        ctx.success({
          name: 'test'
        })
      })
      .get('/error_test', (ctx, next) => {
         ctx.error(code.UNKNOWN_ERROR);
      })
    
    app.use(router.routes());
    app.use(router.allowedMethods());
    
    app.listen(3000);
    
    console.log(`Server is running on port 3000`);
    

     对比两种方式可能有有些疑问,第一种方式,需要传入ctx,而改良之后的方式没有了ctx。那是因为在中间件中做了如下处理

    const { success, error } = require('./util');
    
    module.exports = async (ctx, next) => {
        ctx.success = success.bind(null, ctx);
        ctx.error = error.bind(null, ctx);
        await next();
    }
    

     这样一来,koa的上下文ctx就会被当作ctx.success的默认第一个参数。针对不同模块的controller,不需要再去单独引用一次依赖包,可以直接通过ctx对中间件进行调用。相对于最初的版本,这样大大的提高了开发的效率。

    写在后面
    对于这个,还是有些顾虑。如果koa之后更新的时候,也出现了success和error的方法,再引入这个包,就会覆盖掉koa方法。
    不知道会不会带来什么问题。

    Pull Request地址

    Github传送门

    个人博客传送门
  • 相关阅读:
    mysql重启.....
    tomcat双向认证
    tomcat单向认证
    tomcat ssi使用
    各种排序
    字符转换
    threeSum问题
    求出0~999之间的所有“水仙花数”并输出
    动态规划
    迷惑一天的代码
  • 原文地址:https://www.cnblogs.com/detectiveHLH/p/9356361.html
Copyright © 2011-2022 走看看