node 中间件使用例子

NodeJS在中间件领域有着较为广泛的应用,他能做一些中间层事件,把服务端一部分的代码抽出来,减少处理冗余事情付出的代价,同时让服务真正做业务处理而不用关心页面的事情

常见的应用场景有:

  1. 跨域:解决跨域问题,前端不需要任何相关配置(当然这部分代码可以放在服务端)

  2. 数据mock:前后端同步开发(这没什么好说的)

  3. 接口整合或拆分:中间层的功能是作为后端接口与客户端界面之间的桥梁。前端首先向中间层发起请求,中间层根据业务逻辑向指定后端服务发起请求,后端返回数据后, 中间层根据前端所需的数据格式、种类进行排序筛选等整合封装,最后返回给前端。

  4. 代理:在开发环境下,可以利用Node.js代理,解决最常见的跨域问题;在线上环境下,我们可以利用代理,转发请求到多个服务端,起到类似于Nginx的负载均衡作用,且Node.js中可以很方便的根据业务架构编写转发逻辑代码,相对Ngnix更加灵活。

  5. 缓存:缓存其实是更靠近前端的需求,用户的动作触发数据的更新,Node.js中间层可以直接处理一部分缓存需求,在Redis中获取热点数据或临时数据。而不需要再去请求后端和数据库。 - 限流:Node.js中间层里,可以针对接口或者路由做响应的限流逻辑开发。

  6. 限流:Node.js中间层里,可以针对接口或者路由做响应的限流逻辑开发。

  7. 日志:相比其他服务端语言,Node.js中间层的日志记录,能更方便快捷的定位问题系统问题是后台服务还是前端问题。

  8. 监控:利用Node.js擅长高并发的请求处理的特性,可以用来做服务流量监控入口监控。

  9. 鉴权:微服务架构加可以将身份认证,权限校验的功能统一提前到中间层,不需要在每个服务里都对请求鉴权,降低代码冗余。此外也可以在Node.js中实现针对不同用户转发到不同后端服务的逻辑,这也是灰度发布的一种实现方式。

  10. 路由:前端更需要掌握页面路由的权限和逻辑,在中间层中对接口数据、路由整合转发,可以实现前端路由和请求接口路由的一致性,而后端服务接口路由可以独立设计,不需要迁就某个客户端所需的路由。

我写了一个demo加深理解,首先解释一下代码目录

代码地址:github地址

看app.js

日志中间件
// 日志中间件
app.use(async (ctx, next) => {
  const start = new Date();
  let ms;
  try {
    await next();
    ms = new Date() - start;
    logger.accessLog(ctx, ms);
  } catch (error) {
    ms = new Date() - start;
    logger.errorLog(ctx, error, ms);
  }
});

每次请求都会往文件输出一条日志方便查找错误,使用的是npm包---log4js,具体封装见/src/logs/logs.js

跨域中间件
// middlewares
app.use(KoaCors())
body解析中间件
//body解析中间件
app.use(bodyParser())
路由中间件
import KoaRouter from '@koa/router'
//路由中间间,routers 是导出的函数
app.use(router.routes()).use(router.allowedMethods());

routers(router)

代码所有的目录入口都是index

import requireIndex from 'es6-requireindex'
import middleswares from '../middlewares';
const controller = require('../controllers');
const modulesFiles = requireIndex(__dirname).modules;
export default (router) => {
  Object.keys(modulesFiles).forEach((item) => {
    modulesFiles[item](router, middleswares, controller)
  })
}

目的是为了配合koa的洋葱模型,

举个例子:

 router.get('/department/list', middleswares.formatBody, controller.department.list);

在处理完路由之后先通过controller处理,然后执行formatBody,再把结果返回,所以写这个回调函数的时候要特别注意

/**
 * 响应数据格式化输出中间件
 * 
 */

module.exports = async (ctx, next) => {
  try {
    await next();//执行路由 这个next函数就是控制器函数,意思先执行处理逻辑,把结果根据自己的格式返回
    if (ctx.body) {
      ctx.body = {
        code: ctx.response.status,
        success: true,
        message: 'success',
        data: ctx.body
      }
    } else {
      ctx.body = {
        code: ctx.response.status,
        success: true,
        message: 'success',
      }
    }
  } catch (err) {
    console.log(err);
    ctx.response.status = err.response.status;
    ctx.body = {
      success: false,
      message: err.response.data.text,
    };
  }
}

不需要经过中间件处理的就写成这样就可以

  router.get('/user', controller.login.userInfo);
相关推荐
abc800211703435 分钟前
前端Bug 修复手册
前端·bug
Best_Liu~38 分钟前
el-table实现固定列,及解决固定列导致部分滚动条无法拖动的问题
前端·javascript·vue.js
_斯洛伐克2 小时前
下降npm版本
前端·vue.js
苏十八3 小时前
前端进阶:Vue.js
前端·javascript·vue.js·前端框架·npm·node.js·ecmascript
st紫月3 小时前
用MySQL+node+vue做一个学生信息管理系统(四):制作增加、删除、修改的组件和对应的路由
前端·vue.js·mysql
乐容4 小时前
vue3使用pinia中的actions,需要调用接口的话
前端·javascript·vue.js
似水明俊德4 小时前
ASP.NET Core Blazor 5:Blazor表单和数据
java·前端·javascript·html·asp.net
至天5 小时前
UniApp 中 Web/H5 正确使用反向代理解决跨域问题
前端·uni-app·vue3·vue2·vite·反向代理
与墨学长5 小时前
Rust破界:前端革新与Vite重构的深度透视(中)
开发语言·前端·rust·前端框架·wasm
H-J-L6 小时前
Web基础与HTTP协议
前端·http·php