node使用Koa2搭建web项目的方法


Posted in Javascript onOctober 17, 2017

随着Node.js的日益火热,各种框架开始层出不穷的涌现出来,Node.js也开始逐渐的被应用到处理服务端请求的场景中。搭建Web项目的框架也随之开始出现——express、koa、koa2、egg等,当然要了解其好坏还是要自己去啃源码的。本文将不会涉及到源码,只是带领初学者简单了解下Koa2的基本使用,欢迎大家在评论中互相交流学习。

注意:koa2使用了ES7的语法,所以使用时请升级Node版本到最新。了解更详细的源码信息可以到git上的koajs/koa去了解

1. 项目目录结构

node使用Koa2搭建web项目的方法

2. 代码逻辑解析

2.1. 包结构文件

[package.json]

{
 "name": "weixin-node-koa",
 "version": "1.0.0",
 "description": "node.js with koa2",
 "private": true,
 "dependencies": {
  "koa": "^2.0.0",
  "koa-router": "^7.0.0",
  "mysql":"2.13.0"
 },
 "scripts": {
  "start": "node app.js"
 },
 "engines": {
  "node": ">=6.0.0"
 },
 "author": "Fly",
 "license": "CENTERM"
}

2.2. 启动入口文件

[app.js]

const Koa = require('koa');
const app = new Koa();
const router2controller = require('./app/router2controller.js');
const config = require('./config/config.local.js');

app.use(router2controller());
app.listen(config.port);
console.log("Server started and listen on port " + config.port);

如果请求的报文体是XML格式,可以添加下面的代码自动解析报文(注意引用koa-xxx的版本要与koa2对应)

const Koa = require('koa');
const app = new Koa();
const router2controller = require('./app/router2controller.js');
const config = require('./config/config.local.js');

//start接收到的xml数据请求单独解析存储
const xmlParser = require('koa-xml-body');
app.use(xmlParser()).use((ctx,next) => {
  ctx.data = ctx.request.body;
  return next();
});
//end

app.use(router2controller());
app.listen(config.port);
console.log("Server started and listen on port " + config.port);

从代码看到引入了一个router2controller.js的文件,这个文件是完成前端请求到具体处理方法的路由过程

2.3. 路由器文件

[router2controller.js]

该类将会自动扫描controller文件夹中的文件来加载请求映射,不需要挨个请求单独配置

koa-router原生提供方法如下:

router
 .get('/', async (ctx,next) => {
  this.body = 'Hello World!';
 })
 .post('/users', async (ctx,next) => {
  //TODO
 })
 .put('/users/:id', async (ctx,next) => {
  //TODO
 })
 .del('/users/:id', async (ctx,next) => {
  //TODO
 });

自动扫描controller包实现方法如下

const fs = require('fs');
const router = require('koa-router')();

function addMapping(router, mapping) {
  for (var url in mapping) {
    if (url.startsWith('GET ')) {
      var path = url.substring(4);
      router.get(path, mapping[url]);
      console.log(`register URL mapping: GET ${path}`);
    } else if (url.startsWith('POST ')) {
      var path = url.substring(5);
      router.post(path, mapping[url]);
      console.log(`register URL mapping: POST ${path}`);
    } else if (url.startsWith('PUT ')) {
      var path = url.substring(4);
      router.put(path, mapping[url]);
      console.log(`register URL mapping: PUT ${path}`);
    } else if (url.startsWith('DELETE ')) {
      var path = url.substring(7);
      router.del(path, mapping[url]);
      console.log(`register URL mapping: DELETE ${path}`);
    } else {
      console.log(`invalid URL: ${url}`);
    }
  }
}

function addControllers(router, dir) {
  fs.readdirSync(__dirname + '/' + dir).filter((f) => {
    return f.endsWith('.js');
  }).forEach((f) => {
    console.log(`process controller: ${f}...`);
    let mapping = require(__dirname + '/' + dir + '/' + f);
    addMapping(router, mapping);
  });
}

module.exports = function (dir) {
  var controllersDir = dir || 'controller';
  addControllers(router, controllersDir);
  return router.routes();
};

2.4. 控制器

[userController.js]

***Controller.js是用来处理具体请求信息以及返回数据的,userController.js中处理了GET请求获取用户信息,POST请求保存用户信息

const userService = require('./../service/userService.js');

var getUserinfo = (ctx, next) => {
  let query = ctx.query;
  let userId = query.id;
  let userInfo = userService.getUserById(userId);

  let html = '<html><body>'
    + '<div> userinfo: ' + userInfo + '</div>'
    + '</body></html>';
  ctx.response.type ='text/html';
  ctx.response.body = html;
};

var saveUserinfo = (ctx, next) => {
  const requestString = ctx.data;
  //TODO数据处理
  Console.log(requestString);
};

module.exports = {
  'GET /getUserinfo': getUserinfo,
  'POST /saveUserinfo': saveUserinfo
};

2.5. 数据处理

[userService.js]

处理封装从***Dao.js获取到的数据返回给Controller

const userDao = require('./../dao/userDao.js');

var getUserById = async (userId) => {
  var users = userDao.getUserById(userId);
  var responseContent = '';
  for(let user of users) {
    reaponseContent += '姓名:' + user.name + ' |';
    reaponseContent += '年龄:' + user.age + ' |';
    reaponseContent += '身高:' + user.height + '<br />';
  }
  return responseContent;
}

module.exports = {
  getUserById : getUserById
};

2.6. 数据获取

[userDao.js]

通过请求传入参数来获取user数据

const mysql = require('./../utils/mysqlUtil.js');

var getUserById = async (userId) => {
  let mysqlOptions = {
    sql : 'select * from table_user where user_id = ?',
    args : [userId]
  };

  var users = await mysql.execQuery(mysqlOptions);
  if(users.length == 0) {
    return null;
  } else {
    return users;
  }
};

module.exports = {
  getUserById : getUserById
};

2.7. 数据库操作

[mysqlUtil.js]

包含了数据库连接池控制,连接建立、释放管理,执行Dao发起的数据库操作请求

const mysql = require('mysql');
const config = require('./../../config/config.local.js');

var connectionPool = mysql.createPool({
  'host' : config.database.host,
  'port':config.database.port,
  'user' : config.database.user,
  'password' : config.database.password,
  'database' : config.database.database,
  'charset': config.database.charset,
  'connectionLimit': config.database.connectionLimit,
  'supportBigNumbers': true,
  'bigNumberStrings': true
});

var release = connection => {
  connection.end(function(error) {
    if(error) {
      console.log('Connection closed failed.');
    } else {
      console.log('Connection closed succeeded.');
    }
  });
};

var execQuery = sqlOptions => {
  var results = new Promise((resolve, reject) => {
      connectionPool.getConnection((error,connection) => {
      if(error) {
        console.log("Get connection from mysql pool failed !");
        throw error;
      }

      var sql = sqlOptions['sql'];
      var args = sqlOptions['args'];

      if(!args) {
        var query = connection.query(sql, (error, results) => {
          if(error) {
            console.log('Execute query error !');
            throw error;
          }

          resolve(results);
        });
      } else {
        var query = connection.query(sql, args, function(error, results) {
          if(error) {
            console.log('Execute query error !');
            throw error;
          }

          resolve(results);
        });
      }

      connection.release(function(error) {
        if(error) {
          console.log('Mysql connection close failed !');
          throw error;
        }
      });
    });
  }).then(function (chunk) {
    return chunk;
  });

  return results;
};

module.exports = {
  release : release,
  execQuery : execQuery
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
起点页面传值js,有空研究学习下
Jan 25 Javascript
jquery实现通用版鼠标经过淡入淡出效果
Jun 15 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
Dec 31 Javascript
BootStrap Fileinput初始化时的一些参数
Dec 30 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
Mar 17 Javascript
webpack手动配置React开发环境的步骤
Jul 02 Javascript
说说Vuex的getters属性的具体用法
Apr 15 Javascript
jquery登录的异步验证操作示例
May 09 jQuery
JQuery常见节点操作实例分析
May 15 jQuery
微信小程序如何使用canvas二维码保存至手机相册
Jul 15 Javascript
Layui之table中的radio在切换分页时无法记住选中状态的解决方法
Sep 02 Javascript
webpack介绍使用配置教程详解webpack介绍和使用
Jun 25 Javascript
Node 自动化部署的方法
Oct 17 #Javascript
利用JS实现scroll自定义滚动效果详解
Oct 17 #Javascript
jquery实现图片跟随鼠标的实例
Oct 17 #jQuery
vue获取input输入值的问题解决办法
Oct 17 #Javascript
node.js 用socket实现聊天的示例代码
Oct 17 #Javascript
Bootstrap图片轮播效果详解
Oct 17 #Javascript
vue组件之Alert的实现代码
Oct 17 #Javascript
You might like
自动生成文章摘要的代码[PHP 版本]
2007/03/20 PHP
简单的php 验证图片生成函数
2009/05/21 PHP
php之CodeIgniter学习笔记
2013/06/17 PHP
Yii中CGridView禁止列排序的设置方法
2016/07/12 PHP
PHP使用SMTP邮件服务器发送邮件示例
2018/08/28 PHP
php中字符串和整数比较的操作方法
2019/06/06 PHP
学习YUI.Ext 第四天--对话框Dialog的使用
2007/03/10 Javascript
js window.onload 加载多个函数的方法
2009/11/02 Javascript
JS 控件事件小结
2012/10/31 Javascript
javascript学习笔记--数字格式类型
2014/05/22 Javascript
JavaScript 开发工具webstrom使用指南
2014/12/09 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
JavaScript中对DOM节点的访问、创建、修改、删除
2015/11/16 Javascript
获取JS中网页各种高宽与位置的方法总结
2016/07/27 Javascript
js实现一键复制功能
2017/03/16 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
利用JS判断客户端类型你应该知道的四种方法
2017/12/22 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
JavaScript用document.write()输出换行的示例代码
2020/11/26 Javascript
Python写的一个简单监控系统
2015/06/19 Python
Python简单实现enum功能的方法
2016/04/25 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
2018/05/09 Python
Python2.7环境Flask框架安装简明教程【已测试】
2018/07/13 Python
解决python给列表里添加字典时被最后一个覆盖的问题
2019/01/21 Python
美国在线医疗分销商:MedEx Supply
2020/02/04 全球购物
学校采购员岗位职责
2014/01/02 职场文书
单位刻章介绍信范文
2014/01/11 职场文书
军训考核自我鉴定
2014/02/13 职场文书
校园安全演讲稿
2014/05/09 职场文书
2014超市双十一活动策划方案
2014/09/29 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
银行实习推荐信
2015/03/27 职场文书
MySQL非空约束(not null)案例讲解
2021/08/23 MySQL
css 边框添加四个角的实现代码
2021/10/16 HTML / CSS
instantclient客户端 连接oracle数据库
2022/04/26 Oracle