Stick to the rules! Consumer Driven Contracts 04.07.2015 - Confitura PL Marcin Grzejszczak @mgrzejszczak
Aug 06, 2015
Stick to the rules!Consumer Driven Contracts
04.07.2015 - Confitura PL
Marcin Grzejszczak @mgrzejszczak
@confiturapl @mgrzejszczak / @4financeit
Swim for a dreamhttp://swimforadream.com/Adam will swim 18.5 km from Hel to GdyniaMoney for 3 charity organizations
@confiturapl @mgrzejszczak / @4financeit
Marcin Grzejszczak● Software Architect at 4financeIT● Author of "Mockito Instant", "Mockito Cookbook"● Co-author of "micro-infra-spring",
“spring-cloud-zookeeper”, “spring-cloud-sleuth”
Twitter: @MGrzejszczakBlog: http://toomuchcoding.blogspot.comHomepage: http://marcin.grzejszczak.pl
@confiturapl @mgrzejszczak / @4financeit
Agenda
● Short introduction● Real life scenario with a hilarious joke● How does it work?● Live (hopefully) coding● Summary
@confiturapl @mgrzejszczak / @4financeit
Consumer Driven Contracts
● TDD on architectural level○ mistakes occur both in implementation and design
● Try to use API before implementing it
@confiturapl @mgrzejszczak / @4financeit
Real life scenario...
Hi! I’m team X and we have spent weeks to tweak our code to use your API!
@confiturapl @mgrzejszczak / @4financeit
Real life scenario...
That’s so sweet… But we’ve just changed our API because well, it’s ours.
@confiturapl @mgrzejszczak / @4financeit
Real life scenario...
You’ve got to be shitting me! (however it sounds)
@confiturapl @mgrzejszczak / @4financeit
What is a contract?io.codearte.accurest.dsl.GroovyDsl.make { request { method "PUT" url "/fraudcheck" body(''' { “clientPesel":"12345678901", "loanAmount":123.123 } ''' ) headers { header("Content-Type", "application/fraud+json") } } response { status 200 body( """{ "fraudCheckStatus": "OK"}""") headers { header('Content-Type': 'application/fraud+json') } }}
@confiturapl @mgrzejszczak / @4financeit
What is a contract?io.codearte.accurest.dsl.GroovyDsl.make { request { method "PUT" url "/fraudcheck" body(''' { “clientPesel":"12345678901", "loanAmount":123.123 } ''' ) headers { header("Content-Type", "application/fraud+json") } } response { status 200 body( """{ "fraudCheckStatus": "OK"}""") headers { header('Content-Type': 'application/fraud+json') } }}
Groovy DSL
@confiturapl @mgrzejszczak / @4financeit
What is a contract?io.codearte.accurest.dsl.GroovyDsl.make { request { method "PUT" url "/fraudcheck" body(''' { “clientPesel":"12345678901", "loanAmount":123.123 } ''' ) headers { header("Content-Type", "application/fraud+json") } } response { status 200 body( """{ "fraudCheckStatus": "OK"}""") headers { header('Content-Type': 'application/fraud+json') } }}
FOR A GIVEN REQUEST
@confiturapl @mgrzejszczak / @4financeit
What is a contract?io.codearte.accurest.dsl.GroovyDsl.make { request { method "PUT" url "/fraudcheck" body(''' { “clientPesel":"12345678901", "loanAmount":123.123 } ''' ) headers { header("Content-Type", "application/fraud+json") } } response { status 200 body( """{ "fraudCheckStatus": "OK"}""") headers { header('Content-Type': 'application/fraud+json') } }}
WE’LL HAVE SUCH A RESPONSE
@confiturapl @mgrzejszczak / @4financeit
Workflow - Consumer side
CLONE SERVER REPO AND WORK OFFLINE
@confiturapl @mgrzejszczak / @4financeit
Workflow - Consumer side
1) ALTER THE CONTRACT LOCALLY2) GENERATE AND COPY STUBS3) USE STUBS IN CONSUMER TESTS
@confiturapl @mgrzejszczak / @4financeit
What is a stub?
● JSON representation of a Groovy DSL contract
● Understood by Wiremock Http Server Stub
@confiturapl @mgrzejszczak / @4financeit
Workflow - Consumer side
FILE A PULL REQUEST WITH THE PROPOSED CONTRACT
@confiturapl @mgrzejszczak / @4financeit
Server tests - what happens there?
● server has DSLs with contracts
● tests are generated from the contracts
● stubs that consumers can use are generated from the contracts
@confiturapl @mgrzejszczak / @4financeit
Workflow - Server side
● oh, I have a PR with the proposed contract
● I don’t have the implementation ready so my generated tests are failing
● I’ll add the implementation, fix the tests and merge the PR!
@confiturapl @mgrzejszczak / @4financeit
Workflow - Server side
IMPLEMENTATION IS READYI’LL PUBLISH MY STUB!
@confiturapl @mgrzejszczak / @4financeit
Consumer TechnologyWiremock
http://wiremock.orgtestCompile 'com.github.tomakehurst:wiremock:1.56'
{ "request": { "method": "GET", "url": "/hello" }, "response": { "status": 200, "body": "Hello world!", "headers": { "Content-Type": "text/plain" } }}
Configuration
Sample definition
@confiturapl @mgrzejszczak / @4financeit
Server TechnologyAccurate REST
https://github.com/Codearte/accurest
buildscript { repositories { mavenCentral() } dependencies { classpath 'io.codearte.accurest:accurest-gradle-plugin:0.7.0' }}
apply plugin: 'accurest'
@confiturapl @mgrzejszczak / @4financeit
Consumer prepared the contractio.codearte.accurest.dsl.GroovyDsl.make { request { method "PUT" url "/fraudcheck" body(''' { “clientPesel":"1234567890", "loanAmount":99999 } ''' ) headers { header("Content-Type", "application/vnd.fraud.v1+json") } } response { status 200 body( """{ "fraudCheckStatus": "REJECTED", "rejectionReason": "Amount too high" }""") headers { header('Content-Type': 'application/vnd.fraud.v1+json') } }}
@confiturapl @mgrzejszczak / @4financeit
CDC benefits
● Rapid API prototyping
● Non-blocking development
● Behaviour Driven Development
@confiturapl @mgrzejszczak / @4financeit
CDC benefits
● Client tells what he needs
● Quality - continuously checking if contract is valid
@confiturapl @mgrzejszczak / @4financeit
CDC benefits
● if server breaks API compatibility consumer tests fail
● if server adds new API I can reuse it immediately in my tests
@confiturapl @mgrzejszczak / @4financeit
CDC benefits
● The server tests are generated for you
● Any typos / misunderstandings will be found out immediately
@confiturapl @mgrzejszczak / @4financeit
Not so fast...● Maintaining datasets● What exactly to verify for server side?● Breaking changes● Accurest under development
○ I also have to sleep sometimes
@confiturapl @mgrzejszczak / @4financeit
Q&Ahttps://github.com/marcingrzejszczak/2015_confitura_cdc
Accurest: https://github.com/Codearte/accurestMicro-Infra-Spring: https://github.com/4finance/micro-infra-springCDC: http://martinfowler.com/articles/consumerDrivenContracts.html