svrx-docs

Routing 路由的使用

快速起步

你可通过以下命令来快速尝试 svrx 的动态路由功能

touch route.js # create empty routing file
svrx --route route.js

route.js

get('/blog').to.json({ title: 'svrx' });

打开 /blog,你将看到 {title: 'svrx'} 的 json 输出

特性

语法

[method](selector).to.[action](payload)

举个例子

post('/blog').to.proxy('http://music.163.com');

分别对应

其中 to 只是一个介词,可以省略

路由

路由方法

svrx 路由支持 methods 定义的 http methods

⚠️ 由于 delete 与 js 保留字冲突,你可以使用 del() 来创建 DELETE 方法

路由匹配

svrx 路由基于 path-to-regexp 匹配, 和两大平民 Node 框架 expresskoa 相同.

查看 path-to-regexp 来了解更详尽的匹配规则,以下做简要概述

规则解析举例

匹配参数

参数快捷映射

Action:handle 外,大部分 action 在语法上不具备操作 koa 上下文( context ) 的能力,部分 action 做了 参数快捷映射 的支持

sendFile 为例

get('/html/:path.(html|htm)').to.sendFile('./{path}.{0}')

Action 清单

你可以使用路由的 插件接口 来扩展 Action

send

发送响应内容

get('/blog').to.send({ title: 'this is a blog' });

send 是 koa 框架 ctx.body 的语法糖,当 payload 类型不同时有以下默认行为

sendFile

发送文件内容,根据自动文件后缀设置 Content-Type


get('/index.html').to.sendFile('./index.html');

get('/file/:id.html').to.sendFile('./assets/{id}.html')

json

无论 payload 为什么类型,都发送 json 响应

get('/blog').to.json({title: 'svrx'});

redirect(target[, code])

服务端跳转

get('/blog').to.redirect('/user');

⚠️支持参数映射, 如下例

get('/blog/:path(.*)').to.redirect('/user/{path}')

设置响应头,由于 header 并不发送响应内容,你可以串联其他 action

get('/blog')
  .to.header({ 'X-Engine': 'svrx' })
  .json({ code: 200 });

rewrite

路由重写

⚠️支持参数映射

get('/old/:path(.*)').to.rewrite('/svrx/{path}')
get('/svrx(.*)').to.send('Hello svrx')

/old/1/svrx/1 都会返回Hello svrx

由于 rewrite 并不发送响应内容,你也可以串联其他 action

proxy(target[, options])

代理,将 path 代理到 target 服务器。

get('/api(.*)').to.proxy('http://mock.server.com/')
get('/test(.*)').to.proxy('http://mock.server.com/', {
  secure: false,
})
get('/test/:id').to.proxy('http://{id}.dynamic.server.com/')

handle

handle 即定义一个 koa 的中间件,属于全能力 action,以上所有功能都可以使用 handle 来实现, 代价就是可读性的降低.


get('/hello-world').to.handle((ctx)=>{
  ctx.type = 'html'
  ctx.body = '<body>Hello World</body>'
});

此外,handle 也可以接收一个 require 引入的 koa 中间件,比如:

const bodyParser = require('koa-bodyparser');

post('/test/post').to.handle(bodyParser()).handle((ctx) => {
  ctx.type = 'html';
  ctx.body = ctx.request.body;
});

尽可能抽取通用能力为自定义 action,请参考「插件接口」小节

插件接口

插件的 hooks.onCreate 会注入名为 router 对象, 包含三个方法

详细请参考 插件开发指南

完整范例文件

get('/handle(.*)').to.handle((ctx) => { ctx.body = 'handle'; });
get('/blog(.*)').to.json({ code: 200 });
get('/code(.*)').to.send('code', 201);
get('/json(.*)').to.send({ json: true });
get('/text(.*)').to.send('haha');
get('/html(.*)').to.send('<html>haha</html>');
get('/rewrite:path(.*)').to.rewrite('/query{path}');
get('/redirect:path(.*)').to.redirect('localhost:9002/proxy{path}');
get('/api(.*)').to.proxy('http://mock.server.com/')
get('/test(.*)').to.proxy('http://mock.server.com/', {
  secure: false,
})
get('/test/:id').to.proxy('http://{id}.dynamic.server.com/')
get('/query(.*)').to.handle((ctx) => {
  ctx.body = ctx.query;
});
get('/header(.*)')
  .to.header({ 'X-From': 'svrx' })
  .json({ user: 'svrx' });
get('/user').to.json({ user: 'svrx' });

get('/sendFile/:path(.*)').to.sendFile('./{path}');