Guide Development Guide

Domain name routing

Starting from 0.28.0, fibjs 's mq.Routing object supports the HOST method as domain name routing.

1 2 3 4 5 6 7 8 9 10 11 12 13
const 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

Assuming that the domain fibjs.org has been bound to the machine where our application is located (for testing purposes, you can also modify the Hosts locally to achieve this binding effect), and we hope to download it to the machine through file.fibjs.org For file resources in the FILE_DIR directory, we can do this:

1 2 3 4 5 6
const 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 that the compiled front-end application may be released to the machine, such as stored in 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:

1
fileRoutes.host('festatic.fibjs.org', http.fileHandlers('/home/frontend/assets/'))

api server

Suppose there are api servers on your machine, and you want to unify them to the domain name api.fibjs.org , but assign different paths, 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 10
const 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 9
const 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 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 36
const 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 working. If the server listens to the default port of the machine (usually 80), then one will be 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.