Pact Contracts
Supported Pact Specification versions
* When using Pact specification V4, the following interaction types are validated:
Synchronous/HTTPinteractions are compared against an OpenAPI provider contract.Asynchronous/Messagesinteractions (fire-and-forget messaging) are compared against an AsyncAPI provider contract.Synchronous/Messagesinteractions (request/reply messaging) are compared against an AsyncAPI provider contract.
Message interactions require Pact Specification V4. Each message interaction must include a reference to the AsyncAPI operation's operationId; without it, verification fails. See AsyncAPI for details.
Note
This change is critical - the live page currently states the opposite of the new behavior (that message interaction types are ignored). This footnote must be replaced, not appended to.
Notice
ON-PREMISES SUPPORT
Pact Specification Version 3 from release 1.19.0
Pact Specification Version 4 from release 1.25.0
AsyncAPI provider contracts (message interactions) from release 2.6.0
Compatibility with Provider Contracts
Pact contracts may be used in the following situations:
Consumer Contract | Provider Verification |
|---|---|
Pact | Pact |
Pact | OpenAPI (bi-directional) |
Pact (V4 message interactions) | AsyncAPI (bi-directional) |
Message Interactions
Message interactions Asynchronous/Messages and Synchronous/Messages are compared against AsyncAPI provider contracts (AsyncAPI 3.0 or 3.1). Each message interaction must include a reference to the AsyncAPI operation's operationId. This reference is mandatory; without it, verification fails.
Example of the required reference structure in the Pact file:
json
{
"comments": {
"references": {
"AsyncAPI": {
"operationId": "receiveUserEvents"
}
}
}
}In Pact JS V4, use the .reference() method:
.reference('AsyncAPI', 'operationId', 'receiveUserEvents')Strategies to capture consumer contracts
Transform mock files
Some tools allow you to serialise their mocks to file. In this case, you can create a CLI tool to read the mock and transform it into a Pact file. Teams also build custom mock servers using simply HTTP frameworks like ExpressJS with a set of JSON fixture files. One of the benefits of this approach is that if the mocking tool is used in multiple places and languages, you can reuse a single CLI tool.
Examples include Mountebank and Wiremock.
Record/Replay
If you have your own custom mocking server, or want to test against a real environment periodically, a record/replay strategy could be a useful strategy.
Tools like VCR and Polly can record the actual calls your application makes and store them as a fixture file for future use. This makes your tests reliable but introduces the possibility of drift. Converting these mocks into a pact file reduces that possibility.
See our record/replay example for more information.
API integration
Most tools have language specific APIs you can use to introspect the actual calls made to the mocks, in order to review behaviour.
In this mode, you must be careful to serialise only the mocks invoked by the application.
See our Wiremock example for more information.
Converting mocks into a Pact compatible format
When converting your mocks into a pact file, note the following considerations:
You must generate a Pact file that is compatible with one of the supported versions of the Pact Specification (listed in the table above).
You should not include any matchers, unless you are confident in their application.
Matchers are currently ignored by the cross-contract validation process.
You should validate the pact file is correct prior to uploading to Swagger Contract Testing. You can use the JSON schema below or attempt to load it into a stub server.
Below is a pact file based on the Wiremock example project.
{
"consumer": { "name": "pactflow-example-bi-directional-consumer-wiremock" }, // The name of the consumer application
"provider": { "name": "pactflow-example-bi-directional-provider-restassured" }, // the name of the provider application
"interactions": [
{
"description": "POST_/products_f25f7b8e-35f2-4796-bebf-5f61d31d06b3", // Ideally a human readable description of the scenario, if possible
"request": {
"method": "POST",
"path": "/products",
"query": "foo=bar&baz=bat&bat=1&bat=2", // note array syntax is not supported for multiple query params (i.e. the bat param)
"body": {
// this may be any valid JSON value such as a string or object
"id": "27",
"name": "pizza",
"type": "food",
"price": 27.0
},
"headers": { "Content-Type": "application/json" } // key/value pairs of expected headers
},
"response": {
"status": 200,
"headers": { "Content-Type": "application/json" },
"body": { "id": "27", "name": "pizza", "type": "food" }
}
}
],
"metadata": {
"pactSpecification": { "version": "2.0.0" },
"client": {
// These aren't mandatory, but are useful in
"name": "name of the adapter",
"version": "semver compatible version of the adapter"
}
}
}Pact JSON Schema
You can use this JSON schema as a guide to validate your pact generation tool.