Guide Development Guide

Domain name routing

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

1 2 3 4 5 6 7 8 9 10 11 12
const mq = require('mq') const rt = new mq.Routing(); // support *.fibjs.org in Routing rt.host('*.fibjs.org', ...) // support api.fibjs.org in Routing rt.host('api.fibjs.org', ...) // support fibjs.org in Routing rt.host('fibjs.org', ...) rt.append('host', 'fibjs.org', ...)

Let's look at some examples.

Simple example

Simple fileHandlers

Assume that the domain name fibjs.org has been bound to the machine where our application is located (for testing purposes, you can also achieve this binding effect by modifying Hosts locally), and we hope to be file.fibjs.orgable to download file resources in the FILE_DIR directory on the machine , we can do this:

1 2 3 4 5 6
const mq = require('mq') const http = require('http') const fileRoutes = new mq.Routing(); // support file.fibjs.org in Routing 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 published to the machine, for example, saved in /home/frontend/assets/the 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

And if we want to obtain these resources through festatic.fibjs.org, we can write like this:

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 api.fibjs.orgthis domain name, 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 be bound to the current machine

Complex example

If there are no other declarations, 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 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 a traffic distribution based on the domain name The gateway services for different routes have been set up - this means that to complete the same function, you can only use fibjs's mq.Routing without having to install traditional gateway services such as nginx/apache/tomcat/iis.

👉 [ Use of X509 certificate in fibjs ]