跳到主要内容
Huiboxes

Express快速上手

Express以它的简单、易用,可以快速创建强大Api而闻名。本文章是我学习它所做的笔记,包括基础用法和技巧。

后端1分钟阅读

Express以它的简单、易用,可以快速创建强大Api而闻名。本文章是我学习它所做的笔记,包括基础用法和技巧。Express官网文档

const express = require('express');
const app = express();
const port = 8080;
app.use('/', (req, res) => {
// 当访问根目录 '/' 时会返回 'hello world'
res.send('hello world');
});
/**
* 访问 '/api' 时该回调不会执行
* 因为它前面的 '/api' 中的 '/' 被会上面匹配
*/
app.use('/api', (req, res) => {
res.send('hello api');
});
app.listen(port, () => {
console.log(`running on port ${port}`);
});

app.use是使用中间件的方法,里面的回调函数被称为中间件。

app.use(
'/api',
(req, res, next) => {
console.log(0);
next(); // 前面的函数执行完以后,只有执行next,下一个中间件才能执行
},
(req, res, next) => {
console.log(1);
next();
},
(req, res) => {
console.log(2);
},
);

下面是与上面等价的代码:

const middleware = [
(req, res, next) => {
console.log(0);
next();
},
(req, res, next) => {
console.log(1);
next();
},
(req, res) => {
console.log(2);
},
];
app.use('/api', middleware);

Express 根据访问的url匹配对应的函数。有多个函数的话就按照书写的顺序执行,就像将函数放入了队列中。

路由也叫路由中间件。路由中间件写什么路径就匹配什么(可以是正则),和use不同。

router.get('/index', (req, res) => {
// 'index' 可以是正则
res.send('<h1>index page.</h1>');
});

通过上面的方法可以猜测出来,除了get,应该还存在着postput之类的方法。通过跳转到定义,发现果然如此,下面是源码中的接口:

export interface IRouterMatcher<
T,
Method extends 'all' | 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head' = any
>

就算不会TypeScript也可以猜出来,有多个对应着请求方式的方法,除了那个all。这个all方法也可以望词生意,匹配所有HTTP请求的方式。通常使用来加中间件的,如下:

app.all('/auth', function (req, res, next) {
// 对任何访问auth接口的请求进行权限校验
next(); // 继续执行下面的代码
});

通常来说一个应用的接口是较多的,如果全写在一个文件,不方便维护。可以路由部分拆出来,方法如下,下面是主文件(/server.js):

const express = require('express');
const app = express();
const router = require('./router'); // 路由文件在同级目录的router文件夹下 /router/index.js
const port = 8080;
app.use(router); // 没写路径使用中间件会处理所有请求,但是不会影响其它的路由路径。
app.listen(port, () => {
console.log(`running on port ${port}`);
});

下面是路由文件(/router/index.js):

const express = require('express');
const router = express();
router.get('/index', (req, res) => {
res.send('<h1>index page.</h1>');
});
module.exports = router;

有两种方式:

  • 通过req.query
  • 通过req.params
router.get('/index/:id', (req, res) => {
const query = req.query;
const params = req.params;
res.json({ ...query, ...params }); // 以json返回query与params中的所有属性
});

下面是上面代码请求url后的效果: image.png

当路由开始多起来后会发现代码看起来挺不方便的,可以拆分出controller(就是将路由对应的方法拆分出去),如下:

// 路由文件
const express = require('express');
const router = express();
const { list } = require('../controller');
router.get('/list', list);

controller如下:

const list = (req, res, next) => {
res.json([
{ name: 'bob', age: 18 },
{ name: 'jerry', age: 19 },
]);
};
exports.list = list;

当前目录结构如下:

image.png

评论