Domain name routing
Starting from 0.28.0, fibjs
the mq.Routing object supports the HOST method as domain name routing.
1
2
3
4
5
6
7
8
9
10
11
12
13const mq = require('mq')
const rt = new mq.Routing();
// 使得 routes 支持 *.fibjs.org 解析
rt.host('*.fibjs.org', ...)
// 使得 routes 支持 api.fibjs.org 解析
rt.host('api.fibjs.org', ...)
// 使得 routes 支持 www.fibjs.org, other.fibjs.org, *.fibjs.org 解析
rt.host('fibjs.org', ...)
// `rt.host(...args)` 实际上是 `rt.append('host', ...args)` 的别名
rt.append('host', 'fibjs.org', ...)
Let's look at some examples.
Simple example
Simple fileHandlers
Fibjs.org assume that the domain name has been bound to the machine where our application (for testing purposes, you can also achieve this by modifying the Hosts binding effect locally), and we hope file.fibjs.org
you can download the file directory on the machine FILE_DIR resources , We can do this:
1
2
3
4
5
6const mq = require('mq')
const http = require('http')
const fileRoutes = new mq.Routing();
// 对域名 file.fibjs.org 的请求, 以 fileHandler 响应
fileRoutes.host('file.fibjs.org', http.fileHandler(FILE_DIR))
Front-end resource host
A typical scenario is compiled front-end applications may be posted on the machine, such as to keep the /home/frontend/assets/
directory
1
2
3
4
5/home/frontend/assets/index.html
/home/frontend/assets/200.html
/home/frontend/assets/app.839ca9.js
/home/frontend/assets/common.537a50.js
/home/frontend/assets/chunk.d45858.js
If we want to obtain these resources through festatic.fibjs.org, we can write:
1fileRoutes.host('festatic.fibjs.org', http.fileHandlers('/home/frontend/assets/'))
api server
Assume that there api server on your machine, you want them to unify api.fibjs.org
the domain name, but assign a different path, such as:
API Server | Usage | Path |
---|---|---|
http://127.0.0.1:3001 | User Service | /user |
http://127.0.0.1:8080 | Biz1 | /biz1 |
http://127.0.0.1:9007 | Biz2 | /biz2 |
Then you can:
1
2
3
4
5
6
7
8
9
10const mq = require('mq')
const apiRoutes = new mq.Routing();
// proxyTo 是代理请求到对应 origin 的函数
apiRoutes.host('api.fibjs.org', {
'/user': (req) => proxyTo(req, `http://127.0.0.1:3001`),
'/biz1': (req) => proxyTo(req, `http://127.0.0.1:8080`),
'/biz2': (req) => proxyTo(req, `http://127.0.0.1:9007`),
})
Furthermore, if you want the'/biz1' path to only accept http POST requests, you can:
1
2
3
4
5
6
7
8
9const mq = require('mq')
const apiRoutes = new mq.Routing();
apiRoutes.host('api.fibjs.org', {
'/user': (req) => proxyTo(req, `http://127.0.0.1:3001`),
'/biz1': apiRoutes.post((req) => proxyTo(req, `http://127.0.0.1:8080`)),
'/biz2': (req) => proxyTo(req, `http://127.0.0.1:9007`),
})
Note that api.fibjs.org must have been bound to the current machine
Complex example
If there is no other declaration, in the following example, the following functions exist:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 生成带特定 host 的请求
function getRequest({
path = '/',
host = 'www.fibjs.org'
}) {
const req = new http.Request()
req.value = path
req.addHeader('host', host)
return req
}
// 以 method 尝试对 routes 发起一个 header: host=host 的请求
function invokePathFromHost (path, host, method = 'GET') {
const req = getRequest({ path, host })
req.method = method
mq.invoke(routes, req)
const result = req.response.body.readAll()
return result ? result.toString() : result
}
Domain name diversion
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
36const mq = require('mq')
const http = require('http')
const assert = require('assert')
const routes = new mq.Routing();
routes.host('api.fibjs.org', [
{
'/user/information': req => req.response.json({name: 'xicilion'}),
},
req => req.response.body.rewind()
])
// routes.host 方法可以多次调用
routes.host('*.fibjs.org', [
{
'/': req => req.response.json({message: 'I am in root'}),
'/index.html': req => req.response.body.write(`<html><body>hello fibjs</body></html>`),
'/index.js': req => req.response.body.write(`console.log('hello world')`),
'*': (req, domain) => {
req.response.json({message: 'I am fallback'})
}
},
req => req.response.body.rewind()
])
assert.equal( invokePathFromHost('/', 'www.fibjs.org'), `{"message":"I am in root"}` )
assert.equal( invokePathFromHost('/index.html', 'static.fibjs.org'), `<html><body>hello fibjs</body></html>` )
assert.equal( invokePathFromHost('/index.js', 'static.fibjs.org'), `console.log('hello world')` )
assert.equal( invokePathFromHost('/user/information', 'api.fibjs.org'), JSON.stringify({name: 'xicilion'}) )
try {
invokePathFromHost('/', 'fibjs.org')
} catch (error) {
assert.equal(error, 'Error: Routing: unknown routing: fibjs.org')
}
Next, you only need to mount the routes in the above example to an http(s)Server, and it can start to work. If the server listens to the default port of the machine (usually 80), then one is split according to the domain name The gateway services for different routes are built-this means that to accomplish the same function, you can only use fibjs's mq.Routing instead of installing traditional gateway services such as nginx/apache/tomcat/iis.