$ npm install @mutable/proxy
const { Proxy } = require('@mutable/proxy');
const config = { /* your config object */ };
const proxy = new Proxy(config);
const newConfig = { /* your new config object */ };
proxy.updateConfig(newConfig);
Being a major release, v2.0
has inconsistencies with v1.x
that would require
rewriting your application code. Here's a set of brief instructions that would
help you successfully migrate from v1.x
to v2.0
:
-
Clean-up the directory When using
v1.x
, it was recommended to clone the git directory directly into your project. Since the proxy lives inside an npm module now, you can cleanup any source files relating to the proxy (example:src/proxy.js
andsrc/routes.js
), keeping only files relevant to the project (example:src/app.js
). -
Add the new module to your dependencies and import it Add the module to your dependencies in your
package.json
by runningnpm install @mutable/proxy
and import the module into your project. If you're using CommonJS imports, you can writeconst { Proxy } = require('@mutable/proxy')
orimport { Proxy } from '@mutable/proxy'
if you're using something like Babel or TypeScript that transpile ES Modules to CommonJS. -
Update your usage There have been a couple of changes to the external APIs which would require you to change the way you use these APIs in your code.
- We do not expose
Routes
anymore, please remove all references to routes in your codebase. Updating the configuration ofProxy
would update the corresponding routes' configuration, so you can still do whatever you used to do earlier. In case you do something which requires a direct reference to theRoutes
class which isn't permitted by the current model, please let us know on the issue tracker. - The
constructor
now accepts initial configuration. This means you do not need to construct a newProxy
and immediately callupdateConfig
since you can now pass the initial config object directly into the constructor. - Instead of exporting instances of
Proxy
andRoutes
, we export the classes themselves. This means you will have to instantiate your own instances.
- We do not expose
-
Clean-up your
package.json
At this point, yourpackage.json
(which happened to be a replica of the file in the repository) would have a lot of unneeded stuff, including but not limited to, unused dependencies. You are recommended to clean it up appropriately (by using commands such asnpm uninstall
).
An example application before and after the migration might look something like:
// BEFORE
'use strict'
const Meta = require('@mutable/meta')
const routes = require('./routes')
const proxy = require('./proxy')
let config = {}
Meta.config()
.then(c => {
config = c
proxy.updateConfig(config)
routes.updateConfig(config)
Meta.on('configChange', c => proxy.updateConfig(c))
Meta.on('configChange', c => routes.updateConfig(c))
return c
})
.catch(e => {throw e})
// AFTER
const Meta = require('@mutable/meta')
const { Proxy } = require('@mutable/proxy')
Meta.config()
.then(config => {
const proxy = new Proxy(config);
Meta.on('configChange', c => proxy.updateConfig(c))
})
.catch(e => {throw e})
The config object may contain the following keys to specify the behavior of the proxy:
hosts
token
publish
page404
This is the list of hosts and the routes that map to a service.
target
(string
) The URL it is pointing to. It can contain a service which will be replaced with real host.redirect
(boolean
) It will do a 302 redirect to the target.changeHost
(boolean
) It will replace theheaders.host
to the target host so other proxies know how to route.routes
(Object
) If there is a sub path you want to direct recursively.forceHttps
(boolean
) It will do a 301 redirect to https, defaults to false.
A simple example usage would be along the lines of:
{
"target": "http://google.com",
"redirect": true,
"changeHost": true,
"forceHttps": true
}
Further, you can use the following rules for more advanced configuration.
-
You can use
[~]
at the end for adding the rest of the path to your path. Examplehttp://todo/health/helloworld
ofhttp://health/[~]
becomeshttp://health/helloworld
-
You can use
[*]
at the end to add all the original path on top. Examplehttp://todo/health/helloworld
ofhttp://health/[*]
becomeshttp://health/health/helloworld
-
You can surround a varible with {} so it can be used as a wildcard and used in the template of the domain. Example
http://todo/v2/users/pelle/uploads
ofhttp://upload/user/{userid}
becomeshttp://upload/user/pelle
An advanced example usage using the above rules would be along the lines of:
{
"target": "http://example/",
"redirect": true,
"changeHost": true,
"forceHttps": false,
"routes":{
"v1":{
"target": "http://example-1.com/[~]",
"routes":{
"{company}":{
"target": "http://company/{company}"
}
}
}
}
}
Use these to go through to unpublished services.
In the headers, you can just add a "x-mut"
with one of the tokens and you can proxy to the service.
Example "x-mut: 1234567890"
Also you can use "x-mut-host"
with a token to proxy to any host or service.
Example "x-mut-host: http://health/"
will take that host and append the
full path after
It is a white list of services that can be reached by the outside world with no protection like a firewall. You can use tokens to override it and access the service anyway.
When specified, these would be the contents of your custom 404 page.
A sample complete configurations object would look something like this:
{
"hosts": {
"mutable.local": {
"target": "http://www/[~]",
"routes": {
"health": {
"target": "http://health/[~]"
},
"v2":{
"target": "http://www-2/[*]",
"routes": {
"status": {
"target": "http://status.aws.amazon.com",
"redirect": true,
},
"users": {
"target": "http://user.com/[~]",
"routes": {
"{userid}": {
"routes": {
"upload": {
"target": "http://upload/user/{userid}"
}
}
}
}
}
}
}
}
}
},
"token":{
"pelle": "1234567890"
},
"publish": [
"www",
"health",
"upload",
"email",
"corbis"
],
"page404": "<html><head><style>h1{margin: auto; position: absolute; top: 0; left: 0; right: 0; bottom: 0; height: 100px; font-family: 'arial'; font-weight: 100; color: #555; text-align: center; }body{background:#000;}</style></head><body><h1>404 Not Found</h1></body></html>"
}
In order to turn on debug mode, set DEBUG
environment variable to true
.
This is useful for local development when you want to use external devices to access local development API endpoints.
This is done by specifying a custom host IP address as the MYIP
env variable
and adding the IP to the Service Configuration.
MYIP
as the env name and 192.168.1.123
{
"hosts": {
"mutable.local": { },
"192.168.1.123": { }
},
"token": { },
"publish": [ ],
"page404": "<html> </html>"
}
Copyright (c) Mutable Inc. All rights reserved.
Licensed under the MIT license.