En introduksjon til vårskykontrakten

1. Introduksjon

Spring Cloud Contract er et prosjekt som, enkelt sagt, hjelper oss med å skrive Consumer-Driven Contracts (CDC).

Dette sikrer kontrakten mellom en Produsent og en Forbruker, i et distribuert system - for både HTTP-baserte og meldingsbaserte interaksjoner.

I denne raske artikkelen vil vi utforske skriveprøver fra produsent og forbrukerside for Spring Cloud Contract gjennom en HTTP-interaksjon.

2. Produsent - Serversiden

Vi skal skrive en produsent-side CDC, i form av en EvenOddController - som bare forteller om Nummer parameteren er jevn eller odde:

@RestController offentlig klasse EvenOddController {@GetMapping ("/ validate / prime-number") public String isNumberPrime (@RequestParam ("number") Integer number) {return Integer.parseInt (number)% 2 == 0? "Even": "Odd"; }}

2.1. Maven avhengigheter

For produsentens side trenger vi spring-cloud-starter-contract-verifier avhengighet:

 org.springframework.cloud spring-cloud-starter-contract-verifier 2.1.1.RELEASE test 

Og vi må konfigurere spring-cloud-contract-maven-plugin med navnet på vår basetestklasse, som vi vil beskrive i neste avsnitt:

 org.springframework.cloud spring-cloud-contract-maven-plugin 2.1.1.RELEASE true com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass 

2.2. Produsentens sideoppsett

Vi må legge til en basisklasse i testpakken som laster vårkontekst:

@RunWith (SpringRunner.class) @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.MOCK) @DirtiesContext @AutoConfigureMessageVerifier public class BaseTestClass {@Autowired private EvenOddController evenOddController; @Før offentlige ugyldig oppsett () {StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup (evenOddController); RestAssuredMockMvc.standaloneSetup (standaloneMockMvcBuilder); }}

I / src / test / ressurser / kontrakter / pakken, legger vi til teststubber, slik som denne i filen shouldReturnEvenWhenRequestParamIsEven.groovy:

importer org.springframework.cloud.contract.spec.Contract Contract.make {beskrivelse "skal returnere selv når tallinngangen er til og med" forespørsel {metode GET () url ("/ validate / prime-number") {queryParameters {parameter (" nummer "," 2 ")}}} respons {body (" Even ") status 200}} 

Når vi kjører bygningen, plugin genererer automatisk en testklasse som heter ContractVerifierTest som utvider vår BaseTestClass og legger den inn / mål / generert-test-kilder / kontrakter /.

Navnene på testmetodene er avledet fra prefikset “validere_" sammenkoblet med navnene på våre Groovy teststubber. For den ovennevnte Groovy-filen vil det genererte metodenavnet være “Validate_shouldReturnEvenWhenRequestParamIsEven”.

La oss ta en titt på denne automatisk genererte testklassen:

offentlig klasse ContractVerifierTest utvider BaseTestClass {@Test offentlig ugyldig validate_shouldReturnEvenWhenRequestParamIsEven () kaster unntak {// gitt: MockMvcRequestSpecification forespørsel = gitt (); // når: ResponseOptions respons = gitt (). spesifikasjon (forespørsel) .queryParam ("nummer", "2") .get ("/ validere / primtall"); // deretter: assertThat (respons.statusCode ()). er EqualTo (200); // og: String responseBody = respons.getBody (). asString (); assertThat (responseBody) .isEqualTo ("Even"); } 

Bygningen vil også legge til stubbkrukken i vårt lokale Maven-arkiv slik at den kan brukes av forbrukeren vår.

Stubber vil være tilstede i utdatamappen under stubber / kartlegging /.

3. Forbruker - Kundesiden

Forbrukersiden av CDC vil konsumere stubber generert av produsentens side gjennom HTTP-interaksjon for å opprettholde kontrakten, så eventuelle endringer på produsentens side vil bryte kontrakten.

Vi legger til BasicMathController, som vil sende en HTTP-forespørsel for å få svaret fra de genererte stubbene:

@RestController offentlig klasse BasicMathController {@Autowired private RestTemplate restTemplate; @GetMapping ("/ beregne") offentlig streng checkOddAndEven (@RequestParam ("nummer") Heltall) {HttpHeaders httpHeaders = nye HttpHeaders (); httpHeaders.add ("Content-Type", "application / json"); ResponseEntity responseEntity = restTemplate.exchange ("// localhost: 8090 / validate / prime-number? Number =" + number, HttpMethod.GET, new HttpEntity (httpHeaders), String.class); return responseEntity.getBody (); }}

3.1. Maven-avhengighetene

For forbrukerne våre må vi legge til vår-sky-kontrakt-wiremock og vår-sky-kontrakt-stub-runner avhengigheter:

 org.springframework.cloud spring-cloud-contract-wiremock 2.1.1.RELEASE test org.springframework.cloud spring-cloud-contract-stub-runner 2.1.1.RELEASE test 

3.2. Forbrukersideoppsett

Nå er det på tide å konfigurere stub-løperen vår, som vil informere forbrukeren om tilgjengelige stubber i vårt lokale Maven-arkiv:

@RunWith (SpringRunner.class) @SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureJsonTesters @AutoConfigureStubRunner (stubsMode = StubRunnerProperties.StubsMode.OCAL. produsent: +: stubber: 8090 ") offentlig klasse BasicMathControllerIntegrationTest {@Autowired private MockMvc mockMvc; @Test offentlig ugyldig gitt_WhenPassEvenNumberInQueryParam_ThenReturnEven () kaster unntak {mockMvc.perform (MockMvcRequestBuilders.get ("/ beregne? Tall = 2") .contentType (MediaType.APPLICATION_JSON)). () .streng ("Even")); }}

Merk at ID-er eiendommen til @AutoConfigureStubRunner kommentar spesifiserer:

  • com.baeldung.spring.cloud - den groupId av gjenstanden vår
  • vår-sky-kontrakt-produsent - den artefaktId av produsentens stubbkrukke
  • 8090 - porten som de genererte stubber vil kjøre på

4. Når kontrakten er brutt

Hvis vi gjør endringer på produsentens side som direkte påvirker kontrakten uten å oppdatere forbrukersiden, dette kan føre til svikt i kontrakten.

Anta for eksempel at vi skal endre EvenOddController be URI om / validere / endre / primtall på produsentsiden vår.

Hvis vi ikke informerer forbrukeren om denne endringen, vil forbrukeren fremdeles sende sin forespørsel til / validere / primtall URI, og forbrukersiden test tilfeller vil kaste org.springframework.web.client.HttpClientErrorException: 404 Ikke funnet.

5. Sammendrag

Vi har sett hvordan Spring Cloud Contract kan hjelpe oss med å opprettholde kontrakter mellom en tjenesteforbruker og produsent, slik at vi kan presse ut ny kode uten å bekymre oss for å bryte kontraktene.

Og som alltid kan den fulle implementeringen av denne opplæringen finnes på GitHub.