This project is created in order to demonstrate how consumer driven contract testing can be performed using Pact for the following communication methods.
- REST
- Graph QL
- gRPC
- Async Event Publish
- Async Request/Command Send
It consists of four different applications written with Kotlin and Spring Boot, proto files used during gRPC communication and for sharing payload between asynchronously communicating parties.
Pact Broker is used to share contract interations and verifications between consumer and provider services. You need to make Pact Broker running on 80 port in your local environment in order to be able to execute existing contract tests. You can follow the steps provided within this page to install and make it running.
Following is the summary table which shows services and their consumer/provider roles while performing contract testing of different communication methods.
Consumer | Provider | Comm. Method |
---|---|---|
a-service | b-service | REST |
b-service | c-service | gRPC |
b-service | d-service | GraphQL |
c-service | d-service | Async Event |
a-service | d-service | Async Request/Command |
- Demonstrates consumer driven contract testing of REST and Async Request/Command communication mechanisms with the consumer role.
- Exposes REST endpoints to perform experiments via Swagger UI.
- Demonstrates consumer driven contract testing of gRPC and GraphQL communication mechanisms with the consumer role.
- Demonstrates consumer driven contract testing of REST communication mechanism with the provider role.
- Exposes REST endpoints to perform experiments via Swagger UI.
- Demonstrates consumer driven contract testing of async event publish with the consumer role.
- Demonstrates consumer driven contract testing of gRPC with the provider role.
- Exposes REST endpoints to perform experiments via Swagger UI.
- Demonstrates consumer driven contract testing of GraphQL , async event publish and async request/command with the provider role.
- Exposes REST endpoints to perform experiments via Swagger UI.
- GraphiQL Explorer is also accessible via http://localhost:8086/graphiql endpoint.
Note: Currently, async communication endpoints just print events/messages to the console. In the future, Kafka or any other message broker might be added to demonstrate the async communication while services running.
Note: There is also no persistent storage7mechanism used to retrieve or save data processed within services, sample data is simple returned from memory. In the future, H2 in memory database and Spring Data Repository might be added instead of returning hard coded sample data from the memory.
However, neither of those parts are prerequisite to assess how consumer driven contract testing using Pact can be performed for all those different communication methods.
Following pact gradle tasks can be used to publish interactions and check if deployment is possible on the consumer side.
-
pactPublish: You must run this task after executing consumer tests on the consumer side. Executing tests on the consumer side triggers creation of pact contract json files, and pactPublish task makes tehm to be sent to the Pact Broker.
-
canIDeploy: You can run this this whether specified consumer version is deployable or not. You must provide
-Ppacticipant=<consumer-service-name>
-PpacticipantVersion=<consumer-service-version>
arguments to this task before executing it.
If you want to run those services and the Pact broker in your local environment you will need following ports available in your environment.
Application | Port | Protocol |
---|---|---|
a-service | 8083 | HTTP/REST |
b-service | 8084 | HTTP/REST |
c-service | 8085 | HTTP/REST |
c-service | 8082 | gRPC |
d-service | 8086 | HTTP/REST/GraphQL |
Pact Broker | 80 | HTTP/REST |
-
Enabling gRPC contract tests within Pact is made possible using the information provided in this page, so thanks to Ivan Garcia Sainz-Aja for his invaluable contribution.
-
General information shared in these three blog post series 1 , 2 , 3 published by Frank Rosner and Raffael Stein were very useful in organizing my thoughts about what kind of communication methods to test. I also followed their proposed approach to deal with handling contract tests of async request/commands, so thanks to their invaluable contributions as well.