Is simply express middleware. In the examples below I am using Express v4.x.
With npm, saving it as a dependency.
npm i express-subdomain --save
Let's say you want to provide a RESTful API via the url http://api.example.com
var subdomain = require('express-subdomain'); var express = require('express'); var app = express(); // *** Code examples below go here! *** // example.com app.get('/', function(req, res) { res.send('Homepage'); });
var router = express.Router(); //api specific routes router.get('/', function(req, res) { res.send('Welcome to our API!'); }); router.get('/users', function(req, res) { res.json([ { name: "Brian" } ]); });
Now register the subdomain middleware:
app.use(subdomain('api', router)); app.listen(3000);
The API is alive:
http://api.example.com/ --> "Welcome to our API!"
http://api.example.com/users --> "[{"name":"Brian"}]"
app.use(subdomain('v1.api', router)); //using the same router
http://v1.api.example.com/ --> "Welcome to our API!"
http://v1.api.example.com/users --> "[{"name":"Brian"}]"
Say you wanted to ensure that the user has an API key before getting access to it... and this is across all versions.
Note: In the example below, the passed function to subdomain can be just a pure piece of middleware.
var checkUser = subdomain('*.api', function(req, res, next) { if(!req.session.user.valid) { return res.send('Permission denied.'); } next(); }); app.use(checkUser);
This can be used in tandem with the examples above.
Note: The order in which the calls to app.use() is very important. Read more about it here.
app.use(checkUser); app.use(subdomain('v1.api', router));
The subdomains can also be chained, for example to achieve the same behaviour as above:
var router = express.Router(); //main api router var v1Routes = express.Router(); var v2Routes = express.Router(); v1Routes.get('/', function(req, res) { res.send('API - version 1'); }); v2Routes.get('/', function(req, res) { res.send('API - version 2'); }); var checkUser = function(req, res, next) { if(!req.session.user.valid) { return res.send('Permission denied.'); } next(); }; //the api middleware flow router.use(checkUser); router.use(subdomain('*.v1', v1Routes)); router.use(subdomain('*.v2', v2Routes)); //basic routing.. router.get('/', function(req, res) { res.send('Welcome to the API!'); }); //attach the api app.use(subdomain('api', router)); app.listen(3000);
http://api.example.com/ --> Permission denied.
http://api.example.com/ --> Welcome to the API!
http://v1.api.example.com/ --> API - version 1
http://abc.v1.api.example.com/ --> API - version 1
http://v2.api.example.com/ --> API - version 2
http://abc.v2.api.example.com/ --> API - version 2
If you plan to use this middleware while developing locally, you'll have to ensure that your subdomain is listed in your hosts file.
On Linux or OSX, add your subdomain to /etc/hosts:
127.0.0.1 myapp.dev
127.0.0.1 subdomain.myapp.dev
You may not have write permissions on your hosts file, in which case you can grant them:
$ sudo chmod a+rw /etc/hosts
Note: Express parses the request URL for a top level domain, so developing locally without one won't be possible because Express will treat the subdomain as the domain, and the actual domain as a TLD.
On Windows 7 and 8, the hosts file path is %systemroot%\system32\drivers\etc.
Multilevel TLD's, such as .co.uk you have to pass api.example as the subdomain:
app.use(subdomain('api.example', router));
See bmullan91#17 for more info.
Have a look at the tests!