nodejs 后端初试 Koa

编程
Article Directory
  1. 1. NOTE

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
};

这样,一个基本的后端架构就已经初步建立。

Author: 哒琳

Permalink: http://blog.jieis.cn/2022/128459da-3fa2-4ed1-80dd-ea27ad6d7361.html

Comments