Files
spring-cloud-contract/docs/modules/ROOT/pages/getting-started/introducing-spring-cloud-contract.adoc
Marcin Grzejszczak 43318b0b05 Done
2023-09-11 19:00:22 +02:00

131 lines
5.1 KiB
Plaintext

[[getting-started-introducing-spring-cloud-contract]]
= Introducing Spring Cloud Contract
include::partial$_attributes.adoc[]
Spring Cloud Contract moves TDD to the level of software architecture.
It lets you perform consumer-driven and producer-driven contract testing.
[[getting-started-introducing-spring-cloud-contract-history]]
== History
Before becoming Spring Cloud Contract, this project was called https://github.com/Codearte/accurest[Accurest].
It was created by https://twitter.com/mgrzejszczak[Marcin Grzejszczak] and https://twitter.com/jkubrynski[Jakub Kubrynski]
from (https://github.com/Codearte[Codearte]).
The `0.1.0` release took place on 26 Jan 2015, and it became stable with `1.0.0` release on 29 Feb 2016.
[[getting-started-introducing-spring-cloud-contract-why]]
=== Why Do You Need It?
Assume that we have a system that consists of multiple microservices, as the following
image shows:
image::Deps.png[Microservices Architecture]
[[getting-started-introducing-spring-cloud-contract-testing-issues]]
=== Testing Issues
If we want to test the application in the top left corner of the image in the preceding
section to determine whether it can communicate with other services, we could do one of
two things:
- Deploy all microservices and perform end-to-end tests.
- Mock other microservices in unit and integration tests.
Both have their advantages but also a lot of disadvantages.
*Deploy all microservices and perform end-to-end tests*
Advantages:
- Simulates production.
- Tests real communication between services.
Disadvantages:
- To test one microservice, we have to deploy six microservices, a couple of databases,
and other items.
- The environment where the tests run is locked for a single suite of tests (nobody else
would be able to run the tests in the meantime).
- They take a long time to run.
- The feedback comes very late in the process.
- They are extremely hard to debug.
*Mock other microservices in unit and integration tests*
Advantages:
- They provide very fast feedback.
- They have no infrastructure requirements.
Disadvantages:
- The implementor of the service creates stubs that might have nothing to do with
reality.
- You can go to production with passing tests and failing production.
To solve the aforementioned issues, Spring Cloud Contract was created. The main idea is to
give you very fast feedback, without the need to set up the
whole world of microservices. If you work on stubs, then the only applications you need
are those that your application directly uses. The following image shows the relationship
of stubs to an application:
image::Stubs2.png[Stubbed Services]
Spring Cloud Contract gives you the certainty that the stubs that you use were
created by the service that you call. Also, if you can use them, it means that they
were tested against the producer's side. In short, you can trust those stubs.
[[getting-started-introducing-spring-cloud-contract-purposes]]
== Purposes
The main purposes of Spring Cloud Contract are:
- To ensure that HTTP and messaging stubs (used when developing the client) do exactly
what the actual server-side implementation does.
- To promote the ATDD (acceptance test-driven development) method, and the microservices architectural style.
- To provide a way to publish changes in contracts that are immediately visible on both sides.
- To generate boilerplate test code to be used on the server side.
By default, Spring Cloud Contract integrates with http://wiremock.org[Wiremock] as the HTTP server stub.
IMPORTANT: Spring Cloud Contract's purpose is NOT to start writing business
features in the contracts. Assume that we have a business use case of fraud check. If a
user can be a fraud for 100 different reasons, we would assume that you would create two
contracts, one for the positive case and one for the negative case. Contract tests are
used to test contracts between applications, not to simulate full behavior.
[[getting-started-what-is-a-contract]]
== What Is a Contract?
As consumers of services, we need to define what exactly we want to achieve. We need to
formulate our expectations. That is why we write contracts. In other words, a contract is
an agreement on how the API or message communication should look. Consider the following example:
Assume that you want to send a request that contains the ID of a client company and the
amount it wants to borrow from us. You also want to send it to the `/fraudcheck` URL by using
the `PUT` method. The following listing shows a contract to check whether a client should
be marked as a fraud in both Groovy and YAML:
[tabs]
======
groovy::
+
[source,groovy,indent=0,role="primary"]
----
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
----
======
////
////
[source,yaml,indent=0,role="secondary"]
.yaml
----
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
----
IMPORTANT: It is expected that contracts are coming from a **trusted source**. You should never download nor interact with contracts coming from untrusted locations.