视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
node使用Koa2搭建web项目的方法
2020-11-27 22:27:39 责编:小采
文档

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

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

1. 项目目录结构

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
}

下载本文
显示全文
专题