stick to the rules - consumer driven contracts. 2015.07 confitura

42
Stick to the rules! Consumer Driven Contracts 04.07.2015 - Confitura PL Marcin Grzejszczak @mgrzejszczak

Upload: marcin-grzejszczak

Post on 06-Aug-2015

202 views

Category:

Documents


1 download

TRANSCRIPT

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...

@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

Real life scenario...

@confiturapl @mgrzejszczak / @4financeit

CDC building blocks

● Server● Consumer● Contract

@confiturapl @mgrzejszczak / @4financeit

CDC building blocks

@confiturapl @mgrzejszczak / @4financeit

How to make life easier?

Use common contract

@confiturapl @mgrzejszczak / @4financeit

Contract definition

@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

So how am I supposed to work?

@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

Example

@confiturapl @mgrzejszczak / @4financeit

New feature

@confiturapl @mgrzejszczak / @4financeit

Let consumer drive the contract!

@confiturapl @mgrzejszczak / @4financeit

Live coding - consumer side

@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

Time for server side implementation!

@confiturapl @mgrzejszczak / @4financeit

Live coding - server side

@confiturapl @mgrzejszczak / @4financeit

CDC benefits

@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