nodejs 后端初试 Koa
参考廖雪峰JavaScript 教程
新建项目文件夹 my_app 并初始化 koa
1 2 3 4
| mkdir my_app cd my_app npm i Koa npm init
|
新建 app.js 作为出口文件
在 app.js 写入以下代码,新建 Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const Koa = require('koa');
const app = new Koa();
const port = 8001;
app.use(async (ctx, next) => { await next(); ctx.response.type = 'text/html'; ctx.response.body = '<h1>Hello, koa2!</h1>'; });
app.listen(port); console.log(`app start at port ${port}`);
|
运行 node app.js
在浏览器访问 127.0.0.1:8001 运行成功!
NOTE
app.use() 注册了一个异步函数处理请求
1 2 3 4 5
| async (ctx, next) => { await next(); ctx.response.type = 'text/html'; ctx.response.body = '<h1>Hello, koa2!</h1>'; }
|
next 是下一个异步函数,如果没有使用 next() ,那么下一个异步函数将不会被执行。
ctx 是请求体本身
处理 URL
我们可以这样处理 URL
1 2 3 4 5 6 7
| async (ctx, next) => { if (ctx.request.path === '/') { ctx.response.body = 'index page'; } else { await next(); } }
|
不过,当 path 不断增长,app.js 将变得越来越繁杂,将路由提出模块设计,使用 koa-router 库
在项目目录创建目录 controllers 进行路由管理,同时,在项目目录创建一个 controller.js 自动处理 controllers 目录下的路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const fs = require('fs');
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) { let controllers_dir = dir || 'controllers', router = require('koa-router')(); addControllers(router, controllers_dir); return router.routes(); };
|
在 controllers 下,就可以根据模块添加路由,例如,在 controllers 下创建文件 index.js
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var fn_index = async (ctx, next) => { console.log('accept request GET /'); ctx.response.body = `<h1>Index</h1> <form action="/signin" method="post"> <p>Name: <input name="name" value="koa"></p> <p>Password: <input name="password" type="password"></p> <p><input type="submit" value="Submit"></p> </form>`; };
var fn_signin = async (ctx, next) => { var name = ctx.request.body.name || '', password = ctx.request.body.password || ''; console.log(`signin with name: ${name}, password: ${password}`); if (name === 'koa' && password === '12345') { ctx.response.body = `<h1>Welcome, ${name}!</h1>`; } else { ctx.response.body = `<h1>Login failed!</h1> <p><a href="/">Try again</a></p>`; } };
module.exports = { 'GET /': fn_index, 'POST /signin': fn_signin };
|
这样,一个基本的后端架构就已经初步建立。
Comments