This guide walks you through the process of creating a Spring REST application with its contract stubs and consuming the contract within an other Spring application. Spring Cloud Contract Project

What you’ll build

You’ll setup two micro services one providing its contract, and the other one consuming this contract to make sure that the integration to the contract provider service is aligned with the specifications. If in the future, the contract of the producer service changes, then the consumer service’s tests fail catching the potential incompatibility.

What you’ll need

How to complete this guide

Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.

To start from scratch, move on to Build with Gradle.

To skip the basics, do the following:

When you’re finished, you can check your results against the code in gs-contract-rest/complete.

Build with Gradle

First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Gradle and Maven is included here. If you’re not familiar with either, refer to Building Java Projects with Gradle or Building Java Projects with Maven.

Create the directory structure

In a project directory of your choosing, create the following subdirectory structure; for example, with mkdir -p src/main/java/hello on *nix systems:

└── src
    └── main
        └── java
            └── hello

Create a Gradle build file

contract-rest-service/build.gradle

buildscript {
	ext {
		springBootVersion = '2.0.3.RELEASE'
		verifierVersion = '1.2.1.RELEASE'
	}
	repositories { mavenCentral() }
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
		classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifierVersion}"
	}
}

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'spring-cloud-contract'


bootJar {
	baseName = 'contract-rest-service'
	version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories { mavenCentral() }

dependencies {
	compile('org.springframework.boot:spring-boot-starter-web')
	testCompile('org.springframework.boot:spring-boot-starter-test')
	testCompile('org.springframework.cloud:spring-cloud-starter-contract-verifier')
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:Finchley.RELEASE"
	}
}

repositories {
    maven {
        url 'https://repo.spring.io/libs-milestone'
    }
}

contracts {
	packageWithBaseClasses = 'hello'
	baseClassMappings {
		baseClassMapping(".*hello.*", "hello.BaseClass")
	}
}

contract-rest-client/build.gradle

buildscript {
	ext { springBootVersion = '2.0.3.RELEASE' }
	repositories { mavenCentral() }
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
	baseName = 'contract-rest-client'
	version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories { mavenCentral() }

dependencies {
	compile('org.springframework.boot:spring-boot-starter-web')
	testCompile('org.springframework.boot:spring-boot-starter-test')
	testCompile('org.springframework.cloud:spring-cloud-starter-contract-stub-runner')
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:Finchley.RELEASE"
	}
}

repositories {
    maven {
        url 'https://repo.spring.io/libs-milestone'
    }
}

eclipse {
	classpath {
		containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
		containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
	}
}

The Spring Boot gradle plugin provides many convenient features:

  • It collects all the jars on the classpath and builds a single, runnable "über-jar", which makes it more convenient to execute and transport your service.

  • It searches for the public static void main() method to flag as a runnable class.

  • It provides a built-in dependency resolver that sets the version number to match Spring Boot dependencies. You can override any version you wish, but it will default to Boot’s chosen set of versions.