Nodejs

Section-3 Koa 框架的路由与 RESTful API

2019-07-11  本文已影响0人  羽晞yose

Lesson-1 路由简介

什么是路由

如果没有路由,会怎样?

运行前面编写的代码,浏览器访问以下地址
localhost:3000 - 页面呈现hello world
localhost:3000/users - 页面呈现hello world
localhost:3000/users/userid - 页面呈现hello world
上面就是因为没有路由,所以全都做了相同的事,返回相同的结果

推荐一款工具 postman ,可以方便快捷的实现接口请求与获取返回值(当然你依旧可以选择在浏览器控制台里,或新建一个html文件,来执行fetch请求)

路由存在的意义


Lesson-2 自己编写一个 Koa 路由中间件

操作步骤

const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa(); // 实例化koa

// 接受一个函数,该函数为一个中间件
app.use(async (ctx) => {
    switch (ctx.url) {
        case '/':
            ctx.body = "这是主页";
            break;
        case '/user':
            ctx.body = '这是用户页';
            break;
        default: 
            ctx.status = 404; // 直接设置404页面会简单的出现默认的 Not Found
            ctx.body = "page not found!" // 这是相当于实现一个自定义的404页面
            break;
    };
});

app.listen(3000, () => {
    console.log(`start server...`);
});

上面这段代码就实现了一个手写的简单路由,代码很简单应该不用解释吧
为什么上面可以直接使用ctx.url,而不是request.url?因为文档里可以看到下面这部分,这是因为koa底层对 Request 和 Response 做了处理,所以直接使用上下文就可以拿到请求地址


文档截图

接下来继续完善,对user页里对请求方法进行判断

case '/user':
if (ctx.method === 'GET') {
    ctx.body = '这是用户列表页';
} else if (ctx.method === 'POST') {
    ctx.body = '创建用户页';
} else {
    ctx.status = 405; // 直接设置405状态,页面会简单的出现默认的 Method Not Allowed
    ctx.body = '不允许该方法'; // 这是相当于实现一个自定义的405页面
}
getpostman结果截图

继续完善,获取详细用户,所以最终结果如下

const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa(); // 实例化koa

// 接受一个函数,该函数为一个中间件
app.use(async (ctx) => {
    if (ctx.url === '/') {
        ctx.body = "这是主页";
    } else if (ctx.url === '/user') {
        if (ctx.method === 'GET') {
            ctx.body = '这是用户列表页';
        } else if (method === 'POST') {
            ctx.body = '创建用户页';
        } else {
            ctx.status = 405; // 直接设置405状态,页面会简单的出现默认的 Method Not Allowed
            ctx.body = '不允许该方法'; // 这是相当于实现一个自定义的405页面
        }
    } else if (ctx.url.match(/\/user\/\w+/)) {
        const userId = ctx.url.match(/\/user\/(\w+)/)[1];
        ctx.body = `用户${userId}`;
    } else {
        ctx.status = 404; // 直接设置404状态,页面会简单的出现默认的 Not Found
        ctx.body = "page not found!" // 这是相当于实现一个自定义的404页面
    }
});

app.listen(3000, () => {
    console.log(`start server...`);
});

当然自己写这种中间件不仅不完善,而且问题也不少,所以应该尽可能使用社区中的中间件


Lesson-3 使用 koa-router 实现路由

操作步骤

// index.js
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa(); // 实例化koa
const router = new Router(); // 实例化路由

router.get('/', (ctx) => {
    ctx.body = "这是主页"
});

router.get('/user', (ctx) => {
    ctx.body = "这是用户列表"
});

router.post('/user', (ctx) => {
    ctx.body = "创建用户页"
});

router.get('/user/:id', (ctx) => {
    ctx.body = `用户${ctx.params.id}`;
});

// 启动路由
app.use(router.routes());

app.listen(3000, () => {
    console.log(`start server...`);
});

接下来尝试一些高级点的功能,添加前缀,使用前缀优点一个是减少代码量,一个是方便统一管理

const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa(); // 实例化koa
const router = new Router();
// 设置前缀,这样下面就不用每次都写/user了
const userRouter = new Router({prefix: '/user'});

router.get('/', (ctx) => {
    ctx.body = "这是主页"
});

userRouter.get('/', (ctx) => {
    ctx.body = "这是用户列表"
});

userRouter.post('/', (ctx) => {
    ctx.body = "创建用户页"
});

userRouter.get('/:id', (ctx) => {
    ctx.body = `用户${ctx.params.id}`;
});

// 启动路由
app.use(router.routes());
app.use(userRouter.routes());

app.listen(3000, () => {
    console.log(`start server...`);
});

尝试一下另一种用法,做一个模拟的用户拦截,如果请求游客信息,将会被拦截

// 模拟的用户安全,作为安全层
const auth = async (ctx, next) => {
    // 异常前置,如果url地址中是/user/visitor,将会被拦截
    if(ctx.params.id === 'visitor') {
        ctx.throw(401); // 注意别写字符串的401,否则报的是500
    }

    await next();
}

userRouter.get('/:id', auth, (ctx) => {
    ctx.body = `用户${ctx.params.id}`;
});

请求地址:localhost:3000/user/visitor,将会出现 Unauthorized,状态401(未授权),证明被拦截
请求地址:localhost:3000/user/master,将会出现 用户master


拦截请求,状态401

Lesson-4 HTTP options 方法的作用是什么

为何要了解 options 方法的作用

比如以下使用 options 方法请求 http://example.org ,就会罗列出该 URL 所支持的方法请求

罗列所支持的方法请求

HTTP options 方法的作用

allowedMethods 的作用

没加 allowedMethods() 丰富请求头的情况下,使用options方法请求 URL,那么将会返回404


404 Not Found
// index.js,给userRouter添加allowedMethods方法后
app.use(userRouter.allowedMethods());
options方法正常运行,并且请求头多了Allow

而当我们使用未被允许的方法来请求时,这个时候将会返回405(不允许),而这些就是使用router.allowedMethods()丰富请求头带来的好处


405方法不允许

而当我们使用一些生僻的方法的时候,比如使用link方法


501未实现
这是为什么呢?为什么同样是使用不允许的方法,而link方法就会返回501呢?
这是因为Koa只实现了一些常用的方法,比如 GET / POST / PUT / PATCH / DELETE / HEAD / OPTIONS,而使用了一些生僻方法的时候,koa实际上是有能力实现的,但是它并未实现,那么这个时候就会返回501

Lesson-5 RESTful API最佳实践 - 增删改查应该返回什么响应?

操作步骤

const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa(); // 实例化koa
const router = new Router();
// 设置前缀,这样下面就不用每次都写/user了
const userRouter = new Router({prefix: '/user'});

router.get('/', (ctx) => {
    ctx.body = "这是主页"
});

// post(增)、delete(删)、put(改)、get(查)
// 获取用户列表
userRouter.get('/', (ctx) => {
    // 应该返回查询的数据
    ctx.body = [
        {name: '韩梅梅'},
        {name: '李蕾'}
    ];
});

// 获取特定用户
userRouter.get('/:id', (ctx) => {
    ctx.body = `用户${ctx.params.id}`;
});

// 增加/新建用户
userRouter.post('/', (ctx) => {
    // 新建用户,应该返回新建的对象
    ctx.body = {name: '韩梅梅'};
});

// 修改用户
userRouter.put('/', (ctx) => {
    ctx.body = {name: '涵美眉'};
});

// 删除用户
userRouter.delete('/', (ctx) => {
    ctx.status = 204; // 没有内容,但是成功了
});

// 启动路由
app.use(router.routes());
app.use(userRouter.routes());
app.use(userRouter.allowedMethods());


app.listen(3000, () => {
    console.log(`start server...`);
});
上一篇 下一篇

猜你喜欢

热点阅读