Pact –Using Consumer Driven Contracts On the JVM -...
Transcript of Pact –Using Consumer Driven Contracts On the JVM -...
Pact – Using Consumer Driven Contracts On the JVM
Norwegian Labor and Welfare AdministrationDervis Mansuroglu
@dervis_m
§ First published by Martin Fowler and Ian Robinson in 2006– https://www.martinfowler.com/articles/consumerDrivenContracts.html
§ Clients tell an API-provider what they expect
§ Expectations are captured in separate files called contracts
§ Each contract is then shared with the provider
What is Consumer Driven Contracts
§ Contracts are tested on both Consumers and Providers– Consumers test their services interfaces– Providers validate their API’s
§ Breaking changes in the API is visible before deployment– “Can I Deploy?”– Automatically triggered provider tests
§ Traditional mocked integration tests is problematic– External services change – while mocks may be outdated– As a consequence – your integration tests fail
What is Consumer Driven Contracts
§ CDC is an addition – not a replacement to existing testing
§ Integration tests– Requires all external service dependencies to be online– Tests will fail when external services are offline– Costly to run, but gives more confidence to deploy– Can test specific parts of a system– External services can be mocked
§ End-to-end tests – Tests an entire system and builds more confidence– Very costly to write, difficult to run and often time consuming– Often neglected and/of completely ignored
What is Consumer Driven Contracts
End-to-End testing
Java Backend Consumer
Pact-JVM
Java Backend Provider
Pact-JVM
Pact-JVM Consumer JUnit5
Java8
Pact-JVM Provider
Pact-JVM Provider JUnit5
Pact Broker
1
2
3
4
Pact-JVM Consumer
PROVIDER
CONSUMER 1 CONSUMER 2 CONSUMER 3
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
/api/person/5
CODE
A simple example using Maven, Java, Spark and JUnit4.
https://github.com/dervism
PROVIDERCONSUMER 1
CONSUMER 2 CONSUMER 3
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
{“id”: 5,“name”: “Per Olsen”,“age”: 50}
CONSUMER 4
{“id”: 5,“firstname”: “Per”,“lastname”: “Olsen”“age”: 50}
/api/person/5
§ A:– Make new version of your API called v2– /api/person/5 becomes /api/v2/person/5
§ B:– Apply Postel Law / The Robustness Principle
How to deal with this situation
§ "Be conservative in what you send, be liberal in what you accept"
§ Be liberal:– @JsonIgnoreProperties(ignoreUnknown = true)
class Person {...}
§ Be conserative:– mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
Postel’s Law / The Robustness Principle
Multistep release without breaking consumers
name
name
name
namefirstnamelastname
firstnamelastname
namefirstnamelastname
firstnamelastname
firstnamelastname
1 2 3 4
§ Very easy to get started– Own Pact Broker and PostgreSql instances running on Kubernetes– Easy to introduce into existing Maven-projects– Consumer-tests are just normal mocked integration tests
§ Getting confident with the Pact Broker takes time– Git as an alternative
§ Deployment pipelines must be extended with Can-I-Deploy– Understanding the Pact Matrix is difficult without testing yourself– Own scripts? Travelling Ruby? Curl-commands? We did it all.
Experiences
§ We write JUnit 4 and JUnit 5 Consumer and Provider tests– XML-configuration is too verbose– Easier to write (and read) custom process handlers
§ Maven and Gradle plugins work differently– Support for JUnit 5, JDK10– We use the pact-jvm-provider-maven to upload Pact-files
– pactbroker-maven-plugin– Introduced in our Maven-projects without issues
§ maven-surefire-plugin– Compatibility issues with JDK10
Experiences
THANKS
[email protected]@dervis_m