Wiremock - A fallback solution for existing API?
- Views
WireMock is an HTTP mock server. At its core it is web server that can be primed to serve canned responses to particular requests (stubbing) and that captures incoming requests so that they can be checked later (verification).
It also has an assortment of other useful features including record/playback of interactions with other APIs, injection of faults and delays, simulation of stateful behavior.
Assumptions
WireMock can create stub mappings from requests it has received. Combined with its proxying feature this allows you to “record” stub mappings from interaction with existing APIs.
In the real world our API often has many external dependencies and when these dependencies are not available then our API would also stop working.
Regarding above feature of Wiremock, can we use it to record requests and relevant responses of our existing API and replay the results back when there is any outage of our API due to external dependency failures or even when the API itself has issues? So we can treat it as a fallback solution for the existing API?
At least it could serve the purpose seemingly.
Concerns
After taking a deep look into this feature, I find a few drawbacks with this feature (maybe I shouldn’t call it as drawback as Wiremock is not designed for this purpose by nature):
If I make same request multiple times it only records the first one not the last one, so I can’t get latest response for the same request when replay it back. There is another function called record as scenarios, which records all responses for the same request pattern, but that’s not what I am looking for.
It couldn’t work as expected when deploying Wiremock to multiple hosts and put them behind a load balancer - every Wirkmock instance will record only a part of the requests made by clients and when replaying the results back one request could hit any Wiremock instance which might not record any response for this request.
Stub mappings resides in memory before I stop the recording and start a new one, so if the recording runs for long time or big volume of requests hit the Wiremock server it could potentially exhaust all memory allocated to the JVM instance.
Stub mappings are written to disk when the recording is stopped which is not safe and cumbersome.
Stub mappings for same request pattern are written to files with different names between different recordings and it leads to uncertain result for same request pattern when replaying the results back.
Performance impact due to memory intensive usage and disk access and also the proxy adds one extra hop in the network.
Solutions
So how do we make it work if we really want to use it? I had a look at the source code of Wiremock and initial solutions for above items are:
Wiremock replays the results by reversing the order of the stubs and take the first one (which is the one happened at earliest) for duplicate requests, so I can add a parameter in the RecordSpec to tell Wiremock to not reverse the order so it can take the last one instead of the first one
We can use Wiremock admin API to load all existing stubs from a centralized storage before replaying, which is based on solution for disk access issue too
Use Wiremock API to reset the stubs in memory at a regular interval
Change the naming conversion of the stubs so that there is only one copy for duplicate requests with same request pattern.
Write the stubs into Mongo instead of file system
Questions
Implementing first 4 items are quite easy but need more efforts on the last one considering concurrent scenarios. The question is do we think it worths the effort and do we have any other better solution for such use case?