狭义中间件

前言

狭义中间件的要素常见要素如下所示。

  • 一切皆中间件
  • 中间件内操作请求 request
    • 请求拦截
  • 中间件内操作响应 response
    • 响应拦截
  • 中间件内操作上下文 context
    • 直接上下文代理,初始化实例时候挂载代理在app.context
    • 请求过程上下文代理,请求时候挂载代理在ctx
  • 大部分直接被 app.use() 加载
    • 注意: 初始化实例挂载代理context不被app.use()

请求拦截

  1. const Koa = require('koa');
  2. let app = new Koa();
  3. const middleware = async function(ctx, next) {
  4. // 中间件 拦截请求
  5. // 把所有请求不是 /page/ 开头的路径全部抛出500错误
  6. const reqPath = ctx.request.path;
  7. if( reqPath.indexOf('/page/') !== 0 ) {
  8. ctx.throw(500)
  9. }
  10. await next();
  11. }
  12. const page = async function(ctx, next) {
  13. ctx.body = `
  14. <html>
  15. <head></head>
  16. <body>
  17. <h1>${ctx.request.path}</h1>
  18. </body>
  19. </html>
  20. `;
  21. }
  22. app.use(middleware);
  23. app.use(page);
  24. app.listen(3001, function(){
  25. console.log('the demo is start at port 3001');
  26. })

响应拦截

  1. const Koa = require('koa');
  2. let app = new Koa();
  3. const middleware = async function(ctx, next) {
  4. ctx.response.type = 'text/plain';
  5. await next();
  6. }
  7. const page = async function(ctx, next) {
  8. ctx.body = `
  9. <html>
  10. <head></head>
  11. <body>
  12. <h1>${ctx.path}</h1>
  13. </body>
  14. </html>
  15. `;
  16. }
  17. app.use(middleware);
  18. app.use(page);
  19. app.listen(3001, function(){
  20. console.log('the demo is start at port 3001');
  21. })

context挂载代理

  • 请求代理注入

    • 直接被app.use
    • 请求时候才有注入
    • 每次请求的注入都不同
  • 初始化实例(应用)代理注入

    • 直接注入到app.context
    • 初始化应用的时候才注入
    • 只注入一次,每次请求都可以使用

请求时挂载代理context

  1. const Koa = require('koa');
  2. let app = new Koa();
  3. const middleware = async function(ctx, next) {
  4. // 中间件 代理/挂载上下文
  5. // 把所有当前服务的进程PID,内存使用情况方法代理/挂载在ctx上
  6. ctx.getServerInfo = function() {
  7. function parseMem( mem = 0 ) {
  8. let memVal = mem / 1024 / 1024;
  9. memVal = memVal.toFixed(2) + 'MB';
  10. return memVal;
  11. }
  12. function getMemInfo() {
  13. let memUsage = process.memoryUsage();
  14. let rss = parseMem(memUsage.rss);
  15. let heapTotal = parseMem(memUsage.heapTotal);
  16. let heapUsed = parseMem(memUsage.heapUsed);
  17. return {
  18. pid: process.pid,
  19. rss,
  20. heapTotal,
  21. heapUsed
  22. }
  23. }
  24. return getMemInfo()
  25. };
  26. await next();
  27. }
  28. const page = async function(ctx, next) {
  29. const serverInfo = ctx.getServerInfo();
  30. ctx.body = `
  31. <html>
  32. <head></head>
  33. <body>
  34. <p>${JSON.stringify(serverInfo)}</p>
  35. </body>
  36. </html>
  37. `;
  38. }
  39. app.use(middleware);
  40. app.use(page);
  41. app.listen(3001, function(){
  42. console.log('the demo is start at port 3001');
  43. })

初始化实例挂载代理context

  1. const Koa = require('koa');
  2. let app = new Koa();
  3. const middleware = function(app) {
  4. // 中间件在初始化实例 把getServerInfo方法 挂载代理到上下文
  5. app.context.getServerInfo = function() {
  6. function parseMem( mem = 0 ) {
  7. let memVal = mem / 1024 / 1024;
  8. memVal = memVal.toFixed(2) + 'MB';
  9. return memVal;
  10. }
  11. function getMemInfo() {
  12. let memUsage = process.memoryUsage();
  13. let rss = parseMem(memUsage.rss);
  14. let heapTotal = parseMem(memUsage.heapTotal);
  15. let heapUsed = parseMem(memUsage.heapUsed);
  16. return {
  17. pid: process.pid,
  18. rss,
  19. heapTotal,
  20. heapUsed
  21. }
  22. }
  23. return getMemInfo()
  24. };
  25. }
  26. middleware(app);
  27. const page = async function(ctx, next) {
  28. const serverInfo = ctx.getServerInfo();
  29. ctx.body = `
  30. <html>
  31. <head></head>
  32. <body>
  33. <p>${JSON.stringify(serverInfo)}</p>
  34. </body>
  35. </html>
  36. `;
  37. }
  38. app.use(page);
  39. app.listen(3001, function(){
  40. console.log('the demo is start at port 3001');
  41. })