RCH Technologies

The Power Of A Mock API Server



A mock API server imitates a real API server by providing realistic responses to requests. It enables rapid application development, by allowing both the service and the service consumer to be developed in parallel. Taking an example of a purchase on an e-commerce application, and using Wiremock as the API Server, we will give a brief overview of getting started with a Mock API Server.

RCH Technologies

WireMock

WireMock is an HTTP mock server. At its core it is web server that can be primed to serve predetermined responses to particular requests. The WireMock server can be run in its own process, and configured via the Java API, JSON over HTTP, JSON or XML files. For this example, we will focus on json configuration. Once the standalone JAR has been downloaded from here, the mock API server can be started with the following command:

$ java -jar wiremock-standalone-2.27.2.jar --global-response-templating

We have enabled response templating when starting the wiremock which will be explained a litte later. A full list of startup options can be found here

When the WireMock API Server starts up, it will create 2 directories - mappings and __files. As the names suggest, the mappings directory will hold the rules for mapping API requests to responses, and __files will contain the json files with the contents of the response body.


Static Mock

The most basic form of mock is a simple static mock. It returns the same response regardless of the request payload.

RCH Technologies

In this case, the same orderId is returned every time the API is called:

{ "orderId": "1234567890" }

To configure this on the WireMock server, a mapping json file needs to be created:

{ "request" : { "urlPathPattern" : "/api/v1/purchase", "method" : "POST" }, "response" : { "status" : 200, "headers": { "content-type": "text/json;charset=UTF-8" }, "transformers": ["response-template"], "bodyFileName" : "purchaseResponse.json" } }

We then create purchaseResponse.json in __files with the content of the json response:

{ "orderId": "1234567890" }

Each time /api/v1/purchase is called, the same response is returned.


Dynamic Mock

A dynamic mock on the other hand will return configurable response. This is achieved through response templating, which we have already enabled during startup of our mock API server, and in our mapping file. In our e-commerce application, the purchase request might include a parameter that needs to be verified on receipt of the response. A static mock would not be of use in this case. Instead, the Mock API server needs to provide a specific response to the request.

{ "transactionId": 0000000012 "orderId": "1234567890" }

In this case, the API call includes the transactionId in its payload. The mapping file will remain the same, but we can use the transactionId from the request to populate the response

{ "transactionId": {{jsonPath request.body '$.transactionId'}}, "orderId": "1234567890" }

We could also make the orderId dynamic, or add a timestamp to the response:

{ "transactionId": {{jsonPath request.body '$.transactionId'}}, "orderId": "{{randomValue length=10 type='NUMERIC'}}", "timestamp": "{{now}} }

A comprehensive list of options for response templating can be found here


Internal Service Mock

In the previous examples, we looked at how the UI could call a mocked API instead of a real API. However, in the real world, when adding a new service, it may not be called by the UI, but by an internal serivce. Taking the example of an e-commerce application, a purchase request may interact with many different services - Inventory Service, Payment Service, Order Management Service etc.

RCH Technologies

If the Payment Service was being developed, we would want the reservation calls to behave as if the Payment Service was already in place. We can achieve this again using our Mock API Server

RCH Technologies

In this instance, the Purchase Service would call the WireMock until the new Payment Service is ready to be consumed.


Partial Internal Service Mock

In the majority of real world scenarios, this will be the case. The service under development will already be in place, but additional functionality will be provided. This may be the addition of a new API, a new version of an API or a new version of the service.

RCH Technologies

In this case, we want to mock specific parts of the service, but allow the existing services to function as normal. This is possibe using default forwarding and rule priority.

{ "priority": 100, "request": { "url": "/api/*" }, "response": { "proxyBaseUrl": "https://payment.rchtech.ie" } }

We can even decide to add or modify some headers of the request as we proxy through the wiremock. If the header already exists in the request, then its value is replace with that specified in the rule. If its not already present, then the header is added to those specified in the request.

{ "priority": 100, "request": { "url": "/api/*" }, "response": { "additionalProxyRequestHeaders": { "timeout" : 5000 }, "proxyBaseUrl": "https://payment.rchtech.ie" } }

This rule will forward all requests that match the URL in the request to the base URL specified. The evaluation order of the rules is determined by the priority - priority 1 is the most important and will be evaluated first, priority 100 is the least important and will be evaluated last. As a result, if all other rules do not map to a response, this rule will forward on the request to the existing Payment Service.

{ "priority": 20, "request" : { "urlPathPattern" : "/api/v2/payment", "method" : "POST" }, "response" : { "status" : 200, "headers": { "content-type": "text/json;charset=UTF-8" }, "transformers": ["response-template"], "bodyFileName" : "paymentResponse.json" } }

In this example, with both the default and specific rules in place, all requests to /api/v2/payment will return mocked responses, but /api/v1/payment will return actual responses from the Payment Service.

Along with allowing both the service and the service consumer to be developed in parallel, this also allows the features of the new service to be opened to traffic when complete by simply deactivating the rule.

CONTACT

Contact us and we'll get back to you within 24 hours.

Swords, Co. Dublin, Ireland

+353 86 3118747

rchtechnologies@icloud.com