Server-less Wiremock, or Using Wiremock Without an HTTP Server

Featured image for sharing metadata for article

I'm a big fan of using Wiremock for stubbing out HTTP services - it can be run as part of your local tests, and it can be deployed as a standalone executable JAR. It runs by having an HTTP server that translates the incoming HTTP requests to the stubbed JSON/Java response, and has bindings that even allow it to run with Node.JS applications.

I've been looking at running Wiremock as part of an AWS Lambda function to cut down costs when not testing, but have found that the overhead of running the HTTP server inside the Lambda to be a bit more than I'd hoped.

Update 2021-10-21: This article has been amended as from v2.32.0 there is planned to be first-class support for the DirectCallHttpServer, which can be found documented on the official docs site.

Prior to v2.32.0

However, today, I managed to find a way to solve this, which has given us the following speed improvements (taken fairly unscientifically on a locally running AWS Lambda):

  • 45-60% reduction in invocation time
  • ~7-10% better memory footprint
  • ~7-10% cold start reduction

You can find a sample project available at jamietanna/serverless-wiremock. (I'm also very shamelessly stealing the pun server-less from friend and colleague Lewis)

My first foray into this, while looking through the WireMockServer code, was that there's a field for a StubRequestHandler which we could fetch using Reflection - which was my first solution.

However, looking a bit closer, I found that we could instantiate the WireMockApp ourselves, and get access to the handler ourselves:

import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.core.WireMockApp;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.http.StubRequestHandler;
// ...

Options options = WireMockConfiguration.options().usingFilesUnderClasspath("wiremock");
WireMockApp app = new WireMockApp(options, null); // null as there's no container running the HTTP side of things
StubRequestHandler handler = app.buildStubRequestHandler();

Now we've got our handler, we want to invoke it for a given HTTP request, just without sending an actual HTTP request.

To do this, there's a Request interface that the handler expects, and we can then put the data in as needed - for instance with a Lambda, we'd take the API Gateway proxy event and convert it to the Request class.

For brevity I won't show the full implementation, as it can be found in sample repo.

import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.ResponseDefinition;
import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
// ...

Request request = new Request() {
    // fill in with your HTTP data
};
ServeEvent event = handler.handleRequest(request);
ResponseDefinition response  = event.getResponseDefinition();
// then get the matched stub's response, i.e. status code out of `response`

This gives us a really nice, lightweight, solution for running Wiremock without the overhead of HTTP!

Note that this is currently an undocumented use of an internal API - see this issue thread where we're discussing alternatives to make this a public API.

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #java #testing #wiremock.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.