WireMock 3 goes GA!

Oleg Nenashev
Developer Advocate and Community Builder
December 12, 2023

We’re excited to announce the general availability of WireMock 3 - a new baseline that introduces a lot of new features, enhancements and also a number of breaking changes that might require user action. The key changes include:

  • New matchers: JSON schema, form parameters, multi-value parameters, etc.
  • Response templating: path parameters, global state functions and data randomization
  • New extension API and better observability capabilities
  • New extension capabilities including support for gRPC and GraphQL and the new global state management
  • Dropping Java 8 support

In this article we will review the key changes and also provide a migration guide for the WireMock 2 users. Stay tuned for more articles on new protocols and integrations!

What’s new?

Below you can find the key enhancements and breaking changes. There are many more enhancements, bug fixes and chore updates that you can find in the WireMock changelog, from the initial big-bang 3.0.0 release to a number of new features and bugfixes

Request matching options

Rich request matching capabilities have always been one of the major features in WireMock, and we are happy to introduce even more advanced capabilities. Below you can see the example of the key features shipped in WireMock 3.

Form parameters matching

Although it’s been possible to match form parameters via sets of “contains(key=value)” body matchers, this has always been slightly brittle and unintuitive. WireMock 3 now has dedicated form parameter matching in the same style as query parameters. As with any other example in this post, you can use the new capabilities in both JSON configurations and the Java API:


stubFor(post(urlPathEqualTo("/install-tool"))
  .withFormParam("tool", equalTo("WireMock"))
).willReturn(ok()));


{
  "request": {
    "urlPath": "/install-tool",
    "method": "POST",
    "formParameters": {
      "tool": {
        "equalTo": "WireMock"
      }
    }
  },
  "response": {
    "status": 200
  }
}

Learn More: Form Parameter Matching docs

JSON Schema matching

The new matchesJsonSchema() matcher allows request parameters to be checked for conformance against JSON Schema documents. This is primarily intended for use in stubs that accept JSON request bodies but can also be used to apply constraints to individual query, form, header or cookie parameters.


{
  "request" : {
    "urlPath" : "/schema-match",
    "method" : "POST",
    "bodyPatterns" : [ {
      "matchesJsonSchema" : "{\n  \"type\": \"object\",\n  \"required\": [\n    \"name\"\n  ],\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\"\n    },\n    \"tag\": {\n      \"type\": \"string\"\n    }\n  }\n}",
      "schemaVersion" : "V202012"
    } ]
  },
  "response" : {
    "status" : 200
  }
}

Learn More: JSON Schema matching documentation

Multi-value parameters support

It is now possible to match parameters like query and headers that can have multiple values more flexibly with the includes and hasExactly matchers (`havingExactly()` in Java).


// There must be 3 values of id exactly whose values are 1, 2, and 3
stubFor(get(urlPathEqualTo("/things"))
    .withQueryParam("id", havingExactly("1", "2", "3"))
    .willReturn(ok()));

Learn More: Multi-value Parameters Matching

Logical NOT

Completing the set of logical operators available to combine matchers, the “not()” function is now available in Handlebars templates, so you can build complex expressions .

Path templates

URL paths can now be matched using URI templates, conforming to the same subset of the URI template standard as used in OpenAPI. Path variable matchers can also be used in the same manner as query and form parameters.


{
  "request": {
    "urlPathTemplate": "/contacts/{contactId}/addresses/{addressId}"
    "method" : "GET",

  },
  "response" : {
    "status" : 200
  }
}

Learn More: Path Templates documentation

Dynamic responses

Path variables

Where path templates are used for matching, the variable values are available for use in response templates by name so that e.g. you can say {{request.path.contactId}} rather than {{request.path.2}}.

State Extension

A new WireMock State Extension was created by Dirk Bolte and other contributors to introduce global state storage that can be used in response templates. With this extension, you can record a state and then reuse it in future responses as variables:


{
  "request": {},
  "response": {},
  "serveEventListeners": [
    {
      "name": "recordState",
      "parameters": {
        "context": "{{jsonPath response.body '$.id'}}",
        "list": {
          "addLast": {
            "id": "{{jsonPath response.body '$.id'}}",
            "firstName": "{{jsonPath request.body '$.firstName'}}",
            "lastName": "{{jsonPath request.body '$.lastName'}}"
          }
        }
      }
    }
  ]
}

Read more about it in the extension documentation.

Random response data

Another upcoming extension is Faker Extension for WireMock that leverages the popular Data Faker library to generate random, fake but reasonable data for WireMock responses. This extension was created by Shreya Agarwal during Hacktoberfest 2023.


    "response": {
      "status": 200,
        "headers": {
          "Content-Type": "application/json"
        },
        "jsonBody": {
          "name": "{{ random 'Name.first_name' }}",
          "surname": "{{ random 'Name.last_name' }}",
          "country": "{{ random 'Address.country' }}",
          "city": "{{ random 'Address.city' }}",
          "favorite_tool": "WireMock"
        }
     }

This extension is now available for preview. Stay tuned for the public release!

Operations

Sub-events

The ServeEvent which is built up as each request is processed now contains a collection of sub-events so that additional diagnostic information can be attached and exposed via the request log API, hence providing better observability into API mocks and allowing building complex assertions in your tests.

Currently non-match diff reports are attached at sub-events as are a number of significant exceptions thrown by several matchers. For example, you can use it to debug JSON schema matching.

Healthcheck API

A health check API endpoint is now available, primarily for ease of deployment into container orchestrators and Testcontainers modules that verify the startup status. This API exposes general health metrics you can extract, and you can get even more observability with the observability extensions for WireMock, including the existing Metrics, Prometheus and the upcoming OpenTelemetry extensions.

Example: WireMock health check

Webhook network security rules

The network security rules restricting proxy targets are now also applied by the webhooks extension (CVE-2023-41327), and we added resiliency against the DNS Rebinding attacks (CVE-2023-41329) to webhooks. While these patches were backported to WireMock 2.35.1, staying up to date with WireMock 3 releases is highly recommended to protect from the security risks.

Extensibility

In WireMock 3 we changed how the extensions engine works and how the extensions are located and loaded. Now all extensions in the designated directories will be discovered automatically, and the `--extensions` argument with a list of extension classes does not need to be passed as an argument.

We also introduced new versions of all of the request processing extensions, taking ServeEvent as a parameter for more context and the ability to append sub-events. We also added a new ServeEventListener that permits the ServeEvent to be intercepted at 4 different points in the request processing flow.

We also added new extension points for adding custom Handlebars helpers and supplying data to the template engine.

Learn more about the WireMock extensibility and new extension points here.

Breaking changes

There are only a few but important changes that impact the mocking behavior of WireMock:

  • Response templating is enabled in local mode by default when starting programmatically. It is now entirely configured via startup options and customised via the extension interface so ResponseTemplateTransformer should no longer be constructed directly. 2.x code constructing ResponseTemplateTransformer will no longer compile so should be removed or migrated to the 3.x style - See #2349 for detail
  • WireMock Docker Containers now ship WireMock 3 by default, including `latest` and other generic tags. You can still use WireMock 2 images by using the explicit version numbers, 2.35.0 is recommended
  • We changed the order of handling scenarios with transformed stubs. Now all macros are resolved before running the matchers
  • WireMock 3 enables local response templating by default in standalone. Now you do not need a configuration flag for that, and in rare cases there might be errors when raw responses include text matching the Handlebars expression syntax
  • Some unofficial extensions, which are maintained outside the WireMock GitHub organization, may be affected by the breaking changes and may no longer function as expected. See wiremock/wiremock #2323 for the current compatibility status
  • WireMock documentation now points to WireMock 3 by default. You can find the WireMock 2 documentation archive on https://wiremock.org/2.x/docs

In addition, there are many changes in the APIs, packaging and distribution that impact use of WireMock if you declare dependency on it in your Java projects or deploy it as a JAR file:

  • Java 8 is no longer supported, WireMock will NOT work on this version anymore
  • Eclipse Jetty was updated from the 9.x baseline to 11.x If you use WireMock with projects including Jetty, we recommend switching to the `wiremock-standalone` artifact that shades the dependencies
  • The WireMock Docker official image now ships with Eclipse Temurin 17 by default. Java 11 images are available too via tags. Java 8 images are no longer shipped
  • Change the Maven repository groupID to org.wiremock for all artifacts built from this repository: wiremock, wiremock-standalone, wiremock-webhooks-extension
  • Change artifact IDs of wiremock-jre8 and wiremock-jre8-standalone to wiremock and wiremock-standalone
  • Move webhooks and the Webhooks Extension codebase to the WireMock core. Users of the extension should remove the dependency when updating to the new version
  • Change the standalone CLI entrypoint (main()) from com.github.tomakehurst.wiremock.standalone.WireMockServerRunner  to wiremock.Run
  • Almost all Guava usages in public binary APIs were replaced by Java 11 equivalents. The rest will be removed in the WireMock 4 release in the future.
  • Switch the com.github.tomakehurst.wiremock.common.Timing return values to Integer and allow null when data isn't ready
  • Remove deprecated API routes

We also deprecated the legacy recorder (7b8a7d) @tomakehurst and a few other minor APIs. They are slated for removal in WireMock 4.

Please note that some APIs remain in the Beta state, and there might be some breaking changes within major releases. We will be adding more annotations in the next release to make it explicit.

Migrating from WireMock 2.35.1

While there are several breaking changes in Binary API, there should be no impact on the majority of the WireMock users. Key upgrade steps:

  1. If you aren’t using WireMock 2.35.1, upgrade to this version first to get the latest updates and security fixes
  2. If you use WireMock Standalone, backup your configurations, logs and other information you might need in the future, just in case the upgrade goes wrong
  3. If you use any WireMock extensions, proprietary or open source ones, ensure they are compatible with WireMock 3 by checking this GitHub Issue, documentation and the integration tests.
    a. NOTE: If you discover any incompatible extension, please raise a bug in wiremock/wiremock/issues or comment in wiremock/wiremock #2323, We will triage and route it accordingly
  4. If you use Java 8 on the instance, update to Java 11 or Java 17. If you have to keep using Java 8 and want to use WireMock 3 features, consider using the WireMock via our Testcontainers module.
  5. Update WireMock to the most recent release of WireMock 3, taking account of the note above about changes to the Maven group and artifact IDs (now: org.wiremock:wiremock-standalone and org.wiremock:wiremock).

If you use WireMock Cloud in SaaS, no steps needed. The WireMock Inc team takes care of the upgrades, and most of the instances already run on WireMock 3.

Credits

We would like to thank all contributors to WireMock 3 who helped to enhance the release, fixed issues there, and shared their feedback. We had more than 100 contributors to this release, and would like to mention some of them.

  • Bas Dijkstra, Lee Turner, Aaron Goff, Nadia Debogori, Dirk Bolte for contributing to the Community support on Slack and StackOverflow
  • Kapish Malik and Tom Akehurst for the new request matching capabilities
  • Emiliano Alvarez, Joel Schaltenbrand, Basak Gunjan, Yann Tavernier, Yehor Kovalchuk, Arihant Kaushik for improving WireMock APIs and adding new quality-of-life methods for WireMock users
  • Dirk Bolte for adopting the WireMock 3 APIs in the WireMock State Extension and sharing a lot feedback before the 3.0.0 release
  • Tamás Balog for improving WireMock Admin OpenAPI specification, and for reporting issues and documentation gaps
  • Tim te Beek, Tomas Bjerre and pks-1981 for the work on code quality and Guava dependencies clean up. Special thanks to the OpenRewrite project contributors for a great tool!
  • Eric Deandrea and Alejandro Lorefice for sharing feedback and contributing to the WireMock gRPC extension
  • Maciej Walkowiak for the WireMock Spring Bofot library that aligns WireMock 3 and Spring Boot 3
  • Eiki Hayashi for creating the GraphQL extension and adapting it to WireMock 3
  • Jason Anderson, Tamás Balog for reporting issues in WireMock 3 beta and final releases so that we could fix them quickly
  • Numa Canedo and W0rty for discovering and reporting the security issues
  • Pieter-Jan Drouillon, Eiki Hayashi, Oleg Šelajev, Bas Dijkstra, Elias Nogueira, Helber Belmiro, Siva Prasad Reddy K, Tom Akehurst, Dan Perovich, Sergio del Amo and many end users for spreading the word about new WireMock features
  • Mike Waites, Nikita Karpuk, Eddú Meléndez Gonzales Kapish Malik, Julian Michelmann, Ruslan Isamukhametov, Tushar Vyas and Antoni Kania for contributing to the Testcontainers modules
  • All Hacktoberfest 2023 participants who worked on WireMock core patches, documentation and extensions: Jamie Tanna, Alejandro Lorefice, Dmitry Khozyainov, Shreya Agarwal, Utsav Paul, Lee Turner, Karanja Mutahi, Tomer Ben-Rachel, Dragutin Todorovic, Kapish Malik, Lasso Bautista, Aditya Ghidora, Ayan Joshi, Olivier Vernin, Emmanuel Godwin, Dave Cheng, Noushin Kananian, Yerson Fabian, Akhil Kaparthi, Boris Morris, David Hamilton, Prakhar Sharma, Andrew Khoo.
  • WireMock Inc team: Rob Elliot, Mark Gerrard, Lee Turner, Antonio Perez Dieppa, Rafe Arnold and of course the WireMock creator and BDFL Tom Akehurst for driving the release and architectural changes in the project!

And sorry if we missed anyone! To recognize those who contributed to WireMock 3, by code commits or not, we issued special digital badges and we also intend to send some special WireMock swag to key contributors later this year. If you see yourself on this list or if your name is missing, please fill out this Google Form with your email so that we could review it and follow-up: https://forms.gle/25YNN6xLf9bUJgmS7

WireMock 3 contributor badge

What’s next?

In the WireMock 3.0.0 we released the key breaking changes, especially in binary APIs. This builds a foundation for the major enhancements and features we want to introduce. There are many enhancements integrated along the way and many features were released as preview. Here are the key objectives for the next months:

  • General availability of the gRPC Extension and GraphQL extension adding support for the respective protocols
  • General availability releases of the Testcontainers modules for Java, Golang and Node.js (the Python one is already GA)
  • Support for YAML configuration files (wiremock/wiremock #2411)
  • Official support and test coverage for Java 21. It will likely include a new distribution that bundles Jetty 12 and hence compatible with the recent versions of Spring Boot 3 (see wiremock/wiremock #2149).
  • General availability of the extension for OpenTelemetry for better observability
  • Updating WireMock extensions maintained outside the official GitHub organization (see wiremock/wiremock #2323)
  • New documentation site and major documentation enhancements, both in terms of the content and navigation

See more initiatives on our public roadmap:

Public WireMock Roadmap (GitHub Project)

We have also started the project for WireMock 4 scoping (see wiremock/wiremock #2329). We plan that WireMock 4 won’t wait for too long, we want to release it once the key changes are ready and there are enough breaking changes to justify a major release. There are quite a few topics we consider:

  • Restructuring JAR deliverables, e.g. splitting the CLI and REST API clients into separate distributions
  • Remove dependency on Guava
  • Dropping support for Java 11 to double down on modern Java versions
  • New extension points: Secret providers, etc.
  • Providing a headless distributions that can be used not only with a specific Jetty version, but also with other web servers

Join us!

If you are interested in being a part of this journey and to participate in the initiatives listed above, we invite you to join the WireMock community and to participate in the efforts as a code or documentation contributor, tester or a stakeholder interested in the features.

/

Latest posts

Have More Questions?