--- title: Isolate Single Service description: Use MockServer as a reverse proxy to route one service to a local debug instance while forwarding all other requests to the real environment. layout: page pageOrder: 10 section: 'Proxy' subsection: true sitemap: priority: 0.7 changefreq: 'monthly' lastmod: 2019-11-10T08:00:00+01:00 ---

During deployment and debugging it can be helpful to run a single application or service or handle a sub-set of requests on a local machine in debug mode. Using MockServer it is easy to selectively forward requests to a local process running in debug mode, all other request can be forwarded to the real services for example running in a QA or UAT environment.

For example a single page application may load static resources such as HTML, CSS and JavaScript from a web server and also make AJAX calls to one or more separate services, as follows:

Single Page Application

To isolate a single AJAX service, for development or debugging, the MockServer can selectively forward specific requests to a local instance of the service:

Isolating Single Service

One of the simplest ways to do this is using Node.js. In the example below all requests matching path "/rest.*" (i.e. starting with /rest) will go to the local machine on port 8080 whereas all other requests will go to a remote machine (i.e. a load balancer or remote server) on ip 192.168.50.10 and port 443.

First create a package.json file as follows:

{
  "name": "mockserver_as_reverse_proxy",
  "version": "1.0.0",
  "main": "server.js",
  "dependencies": {
    "mockserver-node": "{{ site.mockserver_version }}",
    "mockserver-client": "{{ site.mockserver_version }}"
  }
}<

Then create the server.js file that starts MockServer and sets up the forwarding rules as different expectations, as follows:

var mockserver = require('mockserver-node');
var mockServerClient = require('mockserver-client').mockServerClient;
var HTTP_PORT = 1080;

mockserver
    .start_mockserver({
        serverPort: HTTP_PORT
    })
    .then(function () {
        // forward backend REST API request to local machine
        mockServerClient("localhost", HTTP_PORT)
            .mockAnyResponse({
                "httpRequest": {
                    "path": "/rest.*"
                },
                "httpForward": { // local machine Tomcat instance
                    "host": "127.0.0.1",
                    "port": 8080,
                    "scheme": "HTTP"
                },
                "times": {
                    "unlimited": true
                }
            })
            .then(
                function () {
                    // forward all other request to QA environment
                    mockServerClient("localhost", HTTP_PORT)
                        .mockAnyResponse({
                            "httpRequest": {
                                "path": "/.*"
                            },
                            "httpForward": { // QA environment load balancer
                                "host": "192.168.50.10",
                                "port": 443,
                                "scheme": "HTTPS"
                            },
                            "times": {
                                "unlimited": true
                            }
                        })
                        .then(
                            function () {
                                console.log("created expectations");
                            },
                            function (error) {
                                console.log(error);
                            }
                        );
                },
                function (error) {
                    console.log(error);
                }
            );
    });

console.log("started on port: " + HTTP_PORT);

// stop MockServer if Node exist abnormally
process.on('uncaughtException', function (err) {
    console.log('uncaught exception - stopping node server: ' + JSON.stringify(err));
    mockserver.stop_mockserver();
    throw err;
});

// stop MockServer if Node exits normally
process.on('exit', function () {
    console.log('exit - stopping node server');
    mockserver.stop_mockserver();
});

// stop MockServer when Ctrl-C is used
process.on('SIGINT', function () {
    console.log('SIGINT - stopping node server');
    mockserver.stop_mockserver();
    process.exit(0);
});

// stop MockServer when a kill shell command is used
process.on('SIGTERM', function () {
    console.log('SIGTERM - stopping node server');
    mockserver.stop_mockserver();
    process.exit(0);
});

To start the process install the npm module and launch Node.js, as follows:

npm i
node server.js
 

Operating Mode (SIMULATE / SPY / CAPTURE)

MockServer supports three operating modes that control how unmatched requests are handled. Switch between them at runtime without restarting the server.

Mode Matched requests Unmatched requests Use case
SIMULATE Return mock response Return 404 (default) Pure mock — test against a fully controlled set of expectations
SPY Return mock response Forward to real upstream & record Selective mocking — stub specific calls, pass the rest through to a real service
CAPTURE Return mock response Forward to real upstream & record Traffic capture — no expectations needed; record all real traffic for later replay

SIMULATE is the default. SPY and CAPTURE both enable MockServer's proxy-on-no-match behaviour — unmatched requests are forwarded to the real upstream and the interaction is recorded. The practical difference is intent: SPY is used when you have expectations for some calls and want to pass the rest through; CAPTURE is used when you want to record all traffic first (typically with no expectations defined).

Recorded interactions are retrieved via the existing retrieve endpoints — for example PUT /mockserver/retrieve?type=RECORDED_EXPECTATIONS returns the recorded traffic as expectations ready for replay. See Retrieving Recorded Expectations for details.

 

Setting the Mode

curl -v -X PUT "http://localhost:1080/mockserver/mode?mode=SPY"
curl -v -X PUT "http://localhost:1080/mockserver/mode?mode=CAPTURE"
curl -v -X PUT "http://localhost:1080/mockserver/mode?mode=SIMULATE"
 

Reading the Current Mode

Query the current mode at any time:

curl -s "http://localhost:1080/mockserver/mode"

Response:

{
  "mode": "SPY",
  "proxyUnmatchedRequests": true
}

The proxyUnmatchedRequests field reflects whether unmatched requests will be forwarded (true for SPY and CAPTURE, false for SIMULATE).