1
00:00:00,000 --> 00:00:02,960
So it's been, I don't know, two months?

2
00:00:03,200 --> 00:00:04,400
I can't do calendar math.

3
00:00:04,500 --> 00:00:06,260
That was in August since we talked last, right?

4
00:00:07,200 --> 00:00:08,680
Yeah, about Zipkin.

5
00:00:08,900 --> 00:00:09,600
Yes, that's true.

6
00:00:09,780 --> 00:00:14,720
So now, before we get to our meaty topic, what's been going on in those two months?

7
00:00:14,720 --> 00:00:16,980
What goes on in your life over two months?

8
00:00:18,600 --> 00:00:19,140
Oh, plenty.

9
00:00:19,760 --> 00:00:24,440
You can do a final release of Spring Cloud Contract, for example.

10
00:00:25,160 --> 00:00:28,400
Release a bazillion of different libraries.

11
00:00:29,020 --> 00:00:34,260
So, yeah, plenty of stuff can happen, especially in the Spring Cloud team.

12
00:00:35,040 --> 00:00:39,820
And then we were just sort of jumping in here cold, but why don't you introduce yourself?

13
00:00:40,720 --> 00:00:41,100
Oh, yeah.

14
00:00:41,100 --> 00:00:42,900
So my name is Marcin Zrejstak.

15
00:00:43,040 --> 00:00:49,220
I'm working for the Spring Cloud team, focusing mostly on Spring Cloud Sleuth,

16
00:00:49,560 --> 00:00:55,020
so distributed tracing, Spring Cloud Contract, the new kid in the block.

17
00:00:56,040 --> 00:01:06,580
And also, I do quite a lot of automation, so I play around with Concourse and Jenkins, build pipelines, stuff like that.

18
00:01:06,840 --> 00:01:09,200
So, yeah, I'm a testing freak, automation freak.

19
00:01:09,720 --> 00:01:11,540
It all maps to the projects that I work on.

20
00:01:12,780 --> 00:01:19,520
And then, I forget if we went over this last time, but you got hired from industry, as it were.

21
00:01:19,800 --> 00:01:22,440
So you haven't always worked for a vendor.

22
00:01:22,980 --> 00:01:26,360
You have experience actually trying to do stuff, not just sell stuff.

23
00:01:27,240 --> 00:01:28,240
Yeah, yeah, yeah.

24
00:01:28,360 --> 00:01:37,040
So basically, in at least one of the companies I work for, I was doing the inside IT, so to say, right?

25
00:01:37,040 --> 00:01:42,300
So we were building business applications for ourselves, which is also good because, you know, you care.

26
00:01:42,520 --> 00:01:52,220
So you don't have to, like, tell some project manager that, hey, you should also pay for the test that we're going to write

27
00:01:52,220 --> 00:01:54,760
because everybody cares for the software.

28
00:01:55,300 --> 00:01:56,140
So that was interesting.

29
00:01:56,540 --> 00:01:56,700
Yeah.

30
00:01:57,020 --> 00:02:01,140
Now, you gave this talk we were talking about, like, yesterday?

31
00:02:01,380 --> 00:02:01,800
When was it?

32
00:02:01,840 --> 00:02:03,180
It was sometime very recently, right?

33
00:02:03,880 --> 00:02:04,160
Yeah.

34
00:02:04,280 --> 00:02:18,400
So yesterday, there was the Juktoberfest conference here in Poland, in my hometown of Wurz, where also Dave Sire was talking.

35
00:02:18,700 --> 00:02:24,200
So, yeah, yesterday I was talking as well as about Sprinkler Contract, and actually, I think it was pretty nice.

36
00:02:24,560 --> 00:02:24,760
Yeah?

37
00:02:25,000 --> 00:02:26,960
Well, let's get right into it.

38
00:02:27,140 --> 00:02:27,920
I was happy.

39
00:02:27,920 --> 00:02:34,940
Yeah, so what is the idea of, like, contracts and consumer-driven contracts in a services world and all that?

40
00:02:35,040 --> 00:02:41,300
Like, what, other than defining it, like, what are the issues that create the need for it?

41
00:02:41,380 --> 00:02:43,740
Like, whereupon did it come from?

42
00:02:44,660 --> 00:02:51,980
Yeah, that's a very good start to any discussion about a new approach, new tool.

43
00:02:51,980 --> 00:03:03,020
Actually, speaking of the new stuff here, the consumer-driven contracts is a technique or, like, an approach that is almost, I think, 10 years old, so it's not that new.

44
00:03:03,540 --> 00:03:09,340
So it's a good thing to start with, asking a question, like, what problems are we trying to solve?

45
00:03:10,080 --> 00:03:30,620
So when I was working in one of the companies, the problem that we had was that when you have communication between services, let's not even call them microservices, just applications, the problem that we had were the integration tests.

46
00:03:30,620 --> 00:03:32,200
So what are those integration tests?

47
00:03:32,200 --> 00:03:35,840
Because many people use different definition of those tests.

48
00:03:35,840 --> 00:03:47,520
So for us, these were the tests that were run during the building of the app, where you were doing real calls to an A, like, via HTTP, or you had an in-memory database.

49
00:03:48,000 --> 00:03:49,800
So it was more than a unit, right?

50
00:03:49,840 --> 00:03:54,160
There was some integration between some protocols.

51
00:03:55,000 --> 00:04:06,440
So the problem that we had were the integration tests between services, because when you're writing a test, at some point, you will, like, reach a moment where you want to send a request, right?

52
00:04:06,980 --> 00:04:09,840
So what's the idea of testing?

53
00:04:09,840 --> 00:04:16,720
You want to, like, increase the confidence that your software works.

54
00:04:17,740 --> 00:04:24,540
So how can you, like, test this stuff when two applications are talking to each other?

55
00:04:24,620 --> 00:04:32,460
I mean, one of the possibilities is to have the real application set up, like, next to the one that you're testing.

56
00:04:33,280 --> 00:04:36,360
But, you know, it takes a lot of time.

57
00:04:36,880 --> 00:04:41,380
It takes some knowledge to set up the infrastructure.

58
00:04:42,000 --> 00:04:44,740
So it's out of the question, especially during the build time.

59
00:04:44,860 --> 00:04:46,660
So let's not even talk about this.

60
00:04:46,660 --> 00:04:49,660
This makes more sense when you're doing some end-to-end tests, right?

61
00:04:50,300 --> 00:04:54,560
So what you can do is to stub the other service, right?

62
00:04:54,560 --> 00:05:04,020
So we're doing some sort of a mock where you say that, you know, when I'm going to shoot you with a request like this, then this is the response that I would expect.

63
00:05:04,820 --> 00:05:05,680
And we did that.

64
00:05:06,220 --> 00:05:13,800
But the problem was that the moment we wrote the stub of the service that we are calling, it was outdated.

65
00:05:14,760 --> 00:05:19,000
Because, you know, the other team was working on some features or stuff like that.

66
00:05:19,540 --> 00:05:21,220
So this was the first problem.

67
00:05:21,400 --> 00:05:26,420
How can we ensure that the stub that we're using is valid?

68
00:05:27,000 --> 00:05:32,440
The other problem was that there were a bunch of services talking to a monolithic app.

69
00:05:33,420 --> 00:05:38,900
And every team did the same work of stubbing the monolith.

70
00:05:39,700 --> 00:05:42,380
So I was really annoyed that we're wasting time.

71
00:05:42,600 --> 00:05:44,320
I mean, everybody did the same work.

72
00:05:45,480 --> 00:05:48,660
And, like, the problem is that everybody did the same work.

73
00:05:48,760 --> 00:05:49,800
We wasted time on this.

74
00:05:49,960 --> 00:06:00,360
And it was even worse that every stub that we wrote in each of those teams was outdated the moment it was written because the monolith changes over time.

75
00:06:01,360 --> 00:06:06,520
So that was one of the problems, like, the second thing that we wanted to fix.

76
00:06:06,520 --> 00:06:16,360
And the third one, like, that is related to this approach, like, typically the consumer-driven contract approach is the creation of the API.

77
00:06:17,520 --> 00:06:26,520
Because what often happens is that you take a look at the API of a service that you have to integrate with, and you say, it's useless.

78
00:06:26,700 --> 00:06:28,980
I mean, how can you even create such an API, right?

79
00:06:29,440 --> 00:06:35,940
You as a consumer, even the name suggests that the consumer will consume, right?

80
00:06:36,040 --> 00:06:38,400
So he will call the API.

81
00:06:39,480 --> 00:06:41,640
So his voice should be heard.

82
00:06:43,320 --> 00:06:55,800
So what consumer-driven contracts gives you is the approach to create better API that suits the needs of the consumer, because it's the consumer that will make the calls.

83
00:06:55,960 --> 00:07:00,620
Of course, it's not like the consumer can expect everything and the producer should do it.

84
00:07:00,840 --> 00:07:04,280
There has to be some sort of a collaboration between the two.

85
00:07:04,340 --> 00:07:15,620
But the result of this should be a nice API that is, let's say, helping both sides to deliver business features faster.

86
00:07:16,060 --> 00:07:18,440
That makes, you know, there's two things.

87
00:07:18,500 --> 00:07:24,980
One, when I was reading the Spring Cloud documentation of this stuff the other day, yesterday, I guess,

88
00:07:25,480 --> 00:07:37,180
I was thinking, I wonder how much of, like, our understanding of how to do software in, like, let's say the past 15 years has been driven by making testing easier, right?

89
00:07:37,300 --> 00:07:46,880
Like, the whole idea of, like, not the whole idea, but one of the problems, as you described, that you have with integration testing.

90
00:07:46,980 --> 00:07:53,400
Well, first of all, like, you got to have integration testing nowadays, which is more so than testing some individual piece of code.

91
00:07:53,400 --> 00:07:59,460
You've got to test when you put the whole thing together, the whole application together and the dependent services, making sure it works well.

92
00:07:59,580 --> 00:08:05,320
And there's, I was rereading a good, not defense, but reason for this by the, what's the guy's name?

93
00:08:05,380 --> 00:08:14,000
Gary Gruver, the guy who wrote one of my favorite, I don't know, digital transformation, if that's a phrase, books, like, leading the transformation.

94
00:08:14,780 --> 00:08:20,020
And he was basically pointing out, like, unless you're, like, integrating your code work, like, what are you even doing?

95
00:08:20,020 --> 00:08:23,220
You can't move fast enough, basically, as far as getting the software out.

96
00:08:23,400 --> 00:08:28,580
But anyhow, it's, as you point out, it's really difficult to, like, integrate stuff when stuff is moving around.

97
00:08:28,660 --> 00:08:32,420
And so you start thinking about, well, how could I write my code so it was more easy to test?

98
00:08:33,060 --> 00:08:46,200
And, you know, obviously that doesn't drive everything architecturally, but it's got to be, like, at least 15 or 20% of, like, how people design their code nowadays and how they write it so that it can be easily tested.

99
00:08:46,920 --> 00:08:47,760
Yeah, precisely.

100
00:08:47,760 --> 00:08:49,440
I mean, what's the idea of TDD?

101
00:08:51,260 --> 00:08:52,820
It's to make mistakes.

102
00:08:53,540 --> 00:08:56,600
So you sit down, you write a test, thing doesn't work.

103
00:08:56,760 --> 00:08:59,600
So then you start writing the code.

104
00:08:59,820 --> 00:09:00,900
You tweak around, right?

105
00:09:00,940 --> 00:09:02,460
You change it until you're satisfied.

106
00:09:02,640 --> 00:09:04,440
Like, red, green, refactor, that's the very idea.

107
00:09:04,980 --> 00:09:08,620
So you can do the same as a layer of architecture.

108
00:09:09,080 --> 00:09:14,660
So why not play around with the API until you're satisfied as a consumer?

109
00:09:15,460 --> 00:09:19,340
And that's what you can achieve with tools like Spring Cloud Contract.

110
00:09:19,700 --> 00:09:30,180
And then so the second thing I wanted to ask before you go down a rat hole of wonderful explanation is, so, like, what would you, what are things you'd contrast this approach with, right?

111
00:09:30,200 --> 00:09:37,300
Like, if you were to put a knot in front of, you know, consumer-driven contracts, like, what are the alternatives that someone would do?

112
00:09:38,760 --> 00:09:41,160
The alternatives to the approach, right?

113
00:09:41,320 --> 00:09:41,800
Yeah, yeah.

114
00:09:42,640 --> 00:09:53,440
So, I mean, what typically happens at companies is that, like, the producers of the API are just saying how things should be done.

115
00:09:53,960 --> 00:09:56,920
So this is, like, the typical world.

116
00:09:57,240 --> 00:10:02,400
So you have teams, they have their sprints, they have their project managers, owners, whatever.

117
00:10:03,140 --> 00:10:07,760
So, you know, there is a feature to be written.

118
00:10:07,760 --> 00:10:12,380
And one of the teams says, hey, but the other team has to change their API.

119
00:10:13,500 --> 00:10:20,620
So, you know, things start to go crazy that the product owner of one team has to talk to the product owner of the other.

120
00:10:20,780 --> 00:10:24,180
Can you please put that into the sprint because you're missing a feature?

121
00:10:24,680 --> 00:10:26,960
But they say they have more important things to be done.

122
00:10:27,360 --> 00:10:31,440
So the change will take place in 15 months and then you run out of business.

123
00:10:31,820 --> 00:10:34,280
So it can't go like that, right?

124
00:10:34,280 --> 00:10:50,900
So this is also, this consumer-driven contract approach is also an approach to do this sort of a faster and better, let's say, having a better feedback cycle or even faster feature delivery.

125
00:10:51,140 --> 00:11:00,980
Of course, there are some gigantic companies, like, I don't know, Facebook or Twitter, that will not, like, ask every single consumer if they're happy with their API, right?

126
00:11:01,700 --> 00:11:15,080
You can do this until a certain amount of people that, you know, a certain amount of consumers that you can talk to them and, you know, you can, they can drive the change of the API, of the API of the producer.

127
00:11:15,520 --> 00:11:25,040
If you have, if you have many consumers, it's impossible because you would do nothing else but talk and, you know, and adjust the API.

128
00:11:25,460 --> 00:11:27,620
But to some extent, that's possible.

129
00:11:28,120 --> 00:11:37,440
On the other hand, what's, when you have that many consumers, what you can do at least is, you know, publish some version of your API in terms of the stubs.

130
00:11:37,920 --> 00:11:43,380
So that services that integrate with you can, can profit from that because they have a single source of truth.

131
00:11:43,580 --> 00:11:59,360
So, so maybe, maybe one way of putting like, uh, the alternative way, the, the other way that people go about this is, you know, you've, you've got some application and it has a bunch of services, uh, different components, if you will, different services that, uh, different teams make.

132
00:11:59,480 --> 00:12:05,220
And in these teams, they'll specify the, the API or how the service is used.

133
00:12:05,580 --> 00:12:15,720
And in a more traditional approach, uh, basically that team has probably not, not to make it too much of a straw, man, they don't have complete control over it.

134
00:12:15,720 --> 00:12:19,120
Like they need to like talk with other people and see if it works out.

135
00:12:19,240 --> 00:12:33,060
But the issue is that if you want to modify that API, which is to say, either take something away or add something new, you essentially, uh, have to, you're at risk of breaking the consumers, the people using that API.

136
00:12:33,320 --> 00:12:44,720
And traditionally what you would do is like, as you kind of outlined two things or, or would occur one, uh, you just tell everyone what the new API is and they have to go and update their code and go through that cycle.

137
00:12:44,940 --> 00:12:48,180
Or two, you just deploy it and stuff breaks.

138
00:12:48,500 --> 00:12:54,140
And then each, each team who has something that breaks has to stop what they're doing and fix, fix the thing that's broken.

139
00:12:54,300 --> 00:12:54,860
That's true.

140
00:12:54,960 --> 00:12:55,400
That's true.

141
00:12:55,520 --> 00:12:58,560
So, uh, the idea is that you get immediate feedback.

142
00:12:59,040 --> 00:13:03,620
Um, so it's better to get it before it reaches production.

143
00:13:03,840 --> 00:13:05,120
Uh, yeah, that's the, yeah.

144
00:13:05,300 --> 00:13:14,040
Um, another thing that comes to my mind are things like, you know, protobuf or Afro, where basically this problem disappears to some extent,

145
00:13:14,040 --> 00:13:16,500
because you have a schema, right?

146
00:13:16,820 --> 00:13:24,220
So, so that way, you know exactly how the, uh, it's API looks like of the, of the message that you're sending.

147
00:13:24,620 --> 00:13:34,920
Uh, and here we're talking about, uh, I guess we'll, we'll, we'll be talking about, uh, an approach that can be, uh, used in terms of, uh, rest calls or messaging.

148
00:13:35,360 --> 00:13:35,600
Yeah.

149
00:13:35,600 --> 00:13:40,980
And, and, and, and so, so in both of those cases, you're basically talking about slowing down the process, right?

150
00:13:41,000 --> 00:13:43,400
I mean, well, let me rephrase that.

151
00:13:43,520 --> 00:13:47,300
If you want to prevent errors from happening, right?

152
00:13:47,420 --> 00:13:57,080
Like, like you have to slow down the process that everyone's following, like delaying, you know, release schedules and all of this stuff, which, which is annoying, which, uh, no one likes schedule elongation.

153
00:13:57,080 --> 00:14:14,380
But, you know, but to get incredibly abstract so that we can then get specific, like this, this is an interesting example of how, uh, uh, uh, the problem with computers, which is to say they can only do exactly what you tell them to.

154
00:14:14,600 --> 00:14:21,620
Like, like, like in, in, uh, you know, in any, any, any human language, you have got lots of synonyms and intonations and meanings.

155
00:14:21,620 --> 00:14:26,260
So you could say something like three different ways and basically say the same thing.

156
00:14:26,260 --> 00:14:30,080
And you could even come up with a brand new way of saying something that no one had heard before.

157
00:14:30,320 --> 00:14:32,100
And they'll like, kind of understand it.

158
00:14:32,220 --> 00:14:35,860
But like, when it comes to like programming and computers, like you can't do that.

159
00:14:35,960 --> 00:14:38,140
It's like, I know this one way to talk to an API.

160
00:14:38,680 --> 00:14:42,920
And if you change that, even by like one character, it's going to screw everything up.

161
00:14:43,140 --> 00:14:46,760
And so I have a good story here, but you're completely right.

162
00:14:46,900 --> 00:14:52,420
So in one of the companies that was working there, you know, there is this, uh, Boy Scout rule thing, right?

163
00:14:52,500 --> 00:14:59,060
So you go to the code, you see, like you do some stuff, a feature, but you see a small thing that could be fixed.

164
00:14:59,460 --> 00:15:01,580
So you should fix it like a Boy Scout.

165
00:15:01,580 --> 00:15:07,920
So the problem was that one of the developers saw a typo in the API.

166
00:15:08,820 --> 00:15:19,680
So he fixed it, but he broke all of the collaboration with consumers because they had the typo in their, on their side.

167
00:15:20,140 --> 00:15:20,260
Yeah.

168
00:15:20,400 --> 00:15:27,480
So yeah, that's precisely, uh, what we don't want to have, or we want to break as fast as possible.

169
00:15:27,480 --> 00:15:31,840
So for example, during the building of the app, so at the very beginning of the cycle.

170
00:15:33,540 --> 00:15:34,160
That's right.

171
00:15:34,280 --> 00:15:36,640
It's like, it's like who machine learns the machine learners.

172
00:15:36,980 --> 00:15:38,140
That's, that's the problem.

173
00:15:38,500 --> 00:15:43,000
So, so anyhow, so, so then, so we, we've got this potential problem of like, if you want

174
00:15:43,000 --> 00:15:47,180
to change your, your, uh, your, your APIs or your service definitions or whatever, you're

175
00:15:47,180 --> 00:15:48,660
going to slow things down and break things.

176
00:15:48,660 --> 00:15:51,400
And that's, that's where our hero enters the picture, right?

177
00:15:51,420 --> 00:15:54,500
It's like, so what do we do to solve that problem?

178
00:15:54,500 --> 00:16:00,800
And so like, like you sent over, like, uh, it was way back from 2006 back in the WS star

179
00:16:00,800 --> 00:16:01,620
days and everything.

180
00:16:01,880 --> 00:16:08,180
I, you know, there was a pretty good, uh, description of, of, um, it's a lot easier to understand

181
00:16:08,180 --> 00:16:12,640
if, if you have sort of like, uh, I don't know, a soap sort of background.

182
00:16:12,640 --> 00:16:16,860
Like when I was reading through this thing, like the, the, the, the thing that made the

183
00:16:16,860 --> 00:16:18,400
most sense was what was it called?

184
00:16:18,400 --> 00:16:23,740
Like the principle of ignoring stuff, which was to say, if you're interfacing with an API

185
00:16:23,740 --> 00:16:28,840
and there's a bunch of stuff as a program, you don't understand, just ignore it, which

186
00:16:28,840 --> 00:16:32,540
that doesn't completely solve the problem, but it kind of gets to the theory of like, and

187
00:16:32,540 --> 00:16:38,520
therefore the producer of the API can muck around and, and they can at least add things.

188
00:16:38,520 --> 00:16:42,500
It's still introduces a problem of changing existing stuff, but it's, it's like halfway

189
00:16:42,500 --> 00:16:44,780
to this idea of being able to modify stuff.

190
00:16:45,800 --> 00:16:46,240
Precisely.

191
00:16:46,380 --> 00:16:50,540
So, uh, what we're talking about are not schemas.

192
00:16:50,760 --> 00:16:51,720
Absolutely not.

193
00:16:52,000 --> 00:16:58,920
So maybe before we go on, let's define some common terms that everybody's on the same page.

194
00:16:58,920 --> 00:17:03,920
So to begin with, we have the communication of consumer and producer, right?

195
00:17:04,020 --> 00:17:07,540
So the producer is a service that exposes some API, right?

196
00:17:07,620 --> 00:17:09,640
Let's focus on HTTP here.

197
00:17:10,520 --> 00:17:15,000
So you have a controller, you have an app with a controller, that's a producer.

198
00:17:15,740 --> 00:17:19,060
So the consumer is the service that consumes that API of the producer.

199
00:17:19,260 --> 00:17:24,860
So if you're sending a call to somebody who has a controller, then you're the consumer of

200
00:17:24,860 --> 00:17:25,500
his API.

201
00:17:26,500 --> 00:17:32,340
Now, a contract is an agreement between the producer and consumer on how this API should

202
00:17:32,340 --> 00:17:33,880
look like, right?

203
00:17:33,940 --> 00:17:36,860
So that it's some sort of a written agreement.

204
00:17:37,240 --> 00:17:42,840
And I'm not talking about like word or PowerPoint presentations where we agree on the API has

205
00:17:42,840 --> 00:17:48,700
to be something, uh, that can be a base for our tests and stops.

206
00:17:49,400 --> 00:17:54,540
And the consumer-driven contracts approach is an approach where the consumer drives the changes

207
00:17:54,540 --> 00:17:57,000
of the API of the producer, right?

208
00:17:57,120 --> 00:17:59,200
So we have those four terms.

209
00:17:59,460 --> 00:18:01,440
Now, you mentioned the schema.

210
00:18:01,580 --> 00:18:03,100
So contracts are not schema.

211
00:18:03,780 --> 00:18:11,340
And Spring Cloud contract, a contract is a Groovy file, Groovy DSL, uh, where you can define

212
00:18:11,340 --> 00:18:16,360
that for a particular request, for a particular response should be sent back.

213
00:18:17,980 --> 00:18:24,960
So it's not defining that this is the body of the request that you might send.

214
00:18:25,240 --> 00:18:28,520
And this is the response that you might receive with all the possibilities.

215
00:18:28,720 --> 00:18:29,480
It's not the case.

216
00:18:29,900 --> 00:18:36,500
So if, uh, in the contract you say that, you know, in the body you will send a field full,

217
00:18:36,860 --> 00:18:41,320
but in fact that body can have 500 different fields, I mean, you don't care.

218
00:18:41,400 --> 00:18:43,760
You'd care only about that particular field.

219
00:18:44,240 --> 00:18:45,500
So it's not a schema.

220
00:18:45,640 --> 00:18:48,840
It's sort of a, like a scenario, so to say.

221
00:18:49,560 --> 00:18:51,260
Uh, let's talk about an example.

222
00:18:51,980 --> 00:18:55,580
Yesterday I was giving a talk where the example was buying a beer.

223
00:18:56,380 --> 00:19:03,040
Uh, since, uh, like we talked, uh, uh, the last time I, I told you, I told everybody actually

224
00:19:03,040 --> 00:19:07,640
that the, uh, we have this application called the brewery to test our Spring Cloud stuff.

225
00:19:07,760 --> 00:19:13,640
So of course the sample applications for Spring Cloud contract had to be brew, uh, beer related.

226
00:19:14,140 --> 00:19:21,560
So let's say that we have a case where somebody asks us if they can buy a beer, right?

227
00:19:22,340 --> 00:19:26,860
So we don't have this knowledge to say if the age of the person is okay.

228
00:19:27,100 --> 00:19:33,080
So we have to ask a fraud service, so to say, or like, uh, age check service.

229
00:19:33,320 --> 00:19:36,800
Is this person eligible for, for buying the beer?

230
00:19:37,440 --> 00:19:40,060
So I would assume having two contracts.

231
00:19:40,400 --> 00:19:46,200
One contract would be if a request comes in with a person having an age, I don't know,

232
00:19:46,240 --> 00:19:49,840
greater than 20, then the response will be, uh, you can't get the beer.

233
00:19:51,340 --> 00:19:56,620
So another contract would be if the age is greater than 20, oh yeah, you can get the beer.

234
00:19:56,940 --> 00:19:59,720
So these are two possibilities.

235
00:19:59,880 --> 00:20:08,520
You can get the beer or not, regardless of how many, let's say, fraud cases you would have.

236
00:20:08,780 --> 00:20:15,060
So if the person could be, let's say, declined of having the beer for 100 different reasons,

237
00:20:15,280 --> 00:20:19,060
I would assume most likely that there would, there would be one contract.

238
00:20:19,060 --> 00:20:21,400
Why, why am I emphasizing that?

239
00:20:21,720 --> 00:20:27,320
Because contracts are not supposed to be a duplication of your, of your implementation, right?

240
00:20:27,560 --> 00:20:31,260
Because that way you would have to write the feature twice.

241
00:20:31,500 --> 00:20:33,820
Once in the production code, right?

242
00:20:34,000 --> 00:20:35,720
And once in the contract.

243
00:20:36,160 --> 00:20:42,000
So contract is some sort of an agreement of a subset of, of, uh, features that you have.

244
00:20:42,700 --> 00:20:44,740
Um, and why do we need it?

245
00:20:45,060 --> 00:20:49,260
Because we need something that both sides can agree upon.

246
00:20:49,380 --> 00:20:55,220
So if we're writing a new feature, uh, most likely both the consumer and the producer have

247
00:20:55,220 --> 00:20:55,880
to write something.

248
00:20:56,440 --> 00:21:02,700
So often what happens is that the producer, let's say, starts a sprint earlier than the

249
00:21:02,700 --> 00:21:07,160
consumer, they've done, done something, then the consumers are not happy with the API.

250
00:21:07,320 --> 00:21:11,200
So they have to change, uh, like the producer has to change some stuff again, then the consumer

251
00:21:11,200 --> 00:21:15,940
starts their, their work and, and it's becoming hectic and it takes a lot of time.

252
00:21:15,940 --> 00:21:24,160
So the first thing that should be done is actually agree that a, most likely, uh, this is the

253
00:21:24,160 --> 00:21:26,180
contract that the consumers would like to have.

254
00:21:26,440 --> 00:21:27,740
And, and you start talking.

255
00:21:27,980 --> 00:21:34,460
So the, the contract becomes a written agreement between both sides and what can sprinkle a

256
00:21:34,460 --> 00:21:40,080
contract do with that on the producer side, it can do quite a few things.

257
00:21:40,620 --> 00:21:45,720
Uh, before we go into details, I told you about those two biggest problems.

258
00:21:45,720 --> 00:21:50,640
So stubs, uh, reusability and validity, right?

259
00:21:50,640 --> 00:21:58,660
So how can we ensure that, um, the stubs that the consumers will use are still okay.

260
00:21:59,660 --> 00:22:01,920
And here comes spring cloud contract.

261
00:22:02,320 --> 00:22:10,460
So when the producer writes, uh, like he gets the, the contracts, like those, those, those,

262
00:22:10,460 --> 00:22:16,640
those groovy files, what happens is that the plugins that we have either Maven or Gradle converts

263
00:22:16,640 --> 00:22:22,060
those contracts into tests, what does it mean?

264
00:22:22,500 --> 00:22:29,420
So if in the contract you say, if you send the request at endpoint full, there's going to be a bar response.

265
00:22:29,980 --> 00:22:36,920
We're generating a test that actually sends a request and expects the bar as a response.

266
00:22:37,600 --> 00:22:44,280
So if you don't have such an endpoint, if you're lying in the contract, you will not be able to build yourself.

267
00:22:45,340 --> 00:22:57,400
So that's the, the key thing, uh, that sprinkler contract gives you that the contract is valid only if you, your tests pass, if you, if those, uh, auto-generated tests pass.

268
00:22:57,620 --> 00:22:57,980
Right.

269
00:22:58,640 --> 00:23:02,420
Uh, and then who, who, uh, where do those tests come from?

270
00:23:03,120 --> 00:23:04,140
They are auto-generated.

271
00:23:04,460 --> 00:23:05,520
Ah, right, right, right, right.

272
00:23:05,780 --> 00:23:06,000
Yeah.

273
00:23:06,060 --> 00:23:13,700
So if you write a, um, a couple of contracts using the DSL that we provide, uh, it's statically typed.

274
00:23:13,700 --> 00:23:20,800
So all the groovy haters saying that groovy is dynamic, uh, don't worry, everything is statically typed.

275
00:23:21,240 --> 00:23:23,940
So your ID will help you with, with the DSL.

276
00:23:24,340 --> 00:23:30,940
So what happens is that for every single test, a single contract, a test will be generated on the producer side.

277
00:23:31,660 --> 00:23:35,480
That way we can ensure that you, uh, that the contract tells the truth.

278
00:23:35,940 --> 00:23:44,560
Because the second thing that happens that the, the, the, the, the plugins that we wrote, uh, do is they convert the contracts into stubs.

279
00:23:46,120 --> 00:24:00,660
So that way only after checking whether the producer says the truth in the contract will you, uh, be able to create the, uh, stops that you can publish to Artifactory or Nexus.

280
00:24:01,040 --> 00:24:07,860
So that way we are solving both the reusability and validity problem, right?

281
00:24:08,020 --> 00:24:18,580
So like to recap, contracts give you a written agreement, agreement between the consumer and the producer side, but it's only valid if it's telling the truth, right?

282
00:24:18,820 --> 00:24:25,320
So in order to verify if it's telling the truth, we are creating tests from the contracts.

283
00:24:25,740 --> 00:24:39,800
They are auto-generated and once they pass and all the build pass, we help the developers by creating a jar with the stubs inside that you can publish somewhere where other teams can reuse it.

284
00:24:39,980 --> 00:24:44,180
So they don't have to write like 10 times the same thing.

285
00:24:44,820 --> 00:24:45,260
Right.

286
00:24:45,340 --> 00:24:46,700
I hope I managed to explain it somehow.

287
00:24:47,600 --> 00:25:03,980
And then so, so to, uh, recap and re-explain on, on, uh, on my side, the consumer of what you're producing, so to speak, uh, basically the consumer and the producer get together and, and they, uh, as happens in, in real life, hence the contract metaphor is good.

288
00:25:03,980 --> 00:25:06,740
And they basically agree on a contract, right?

289
00:25:06,740 --> 00:25:11,700
They're like, here is, here is the way we're going to talk with each other as consumer and producer.

290
00:25:11,700 --> 00:25:15,900
And there's like, like, like in your, uh, in your beer buying thing.

291
00:25:15,980 --> 00:25:27,360
I mean, maybe it's actually different than this, so, so you should correct it if so, but it's sort of like there is, uh, there's someone, something that has beer and something that wants beer, a producer of beer and a consumer of it.

292
00:25:27,460 --> 00:25:32,200
And the consumer comes in, and, and, and one of the parts in the contract is requesting a beer.

293
00:25:32,340 --> 00:25:33,820
So there's like, I would like a beer.

294
00:25:34,020 --> 00:25:36,460
So somehow you put in the contract how to do that.

295
00:25:36,600 --> 00:25:43,660
And then, uh, one would hope there's also a part in the contract that allows the producer to give the beer consumer a beer.

296
00:25:43,780 --> 00:25:45,660
So there's sending a beer, so to speak.

297
00:25:45,800 --> 00:25:56,860
But then as you added, there's another step that's basically like, uh, verification that, that it's legal to, uh, to, to give you a beer under whatever geography you're in.

298
00:25:56,980 --> 00:26:03,120
And so there's, I mean, to grossly simplify it, there's basically three things that happen between a consumer and a producer.

299
00:26:03,380 --> 00:26:07,660
And so the contract you would establish is those three things.

300
00:26:07,660 --> 00:26:11,180
And, and then like, how does that, what is that represented in?

301
00:26:11,420 --> 00:26:15,840
Is that like, what, if you were to open that up in a text editor, what is it?

302
00:26:17,000 --> 00:26:18,060
It's a groovy file.

303
00:26:18,320 --> 00:26:25,960
So basically, and it looks, uh, in a very simple way because you have, uh, uh, like I said, it's statically typed.

304
00:26:26,100 --> 00:26:27,240
So the ID helps you.

305
00:26:27,240 --> 00:26:40,960
And you say like, there is a request part when you say for that method, for that URL, for those headers and such a body, I would like such a response that has such a status, such headers.

306
00:26:41,380 --> 00:26:43,060
And such a body, right?

307
00:26:43,060 --> 00:26:47,780
So it's, it's, it's, uh, it's not a schema, as I, as I said, it's some sort of a scenario.

308
00:26:47,780 --> 00:26:55,760
So it gives you much more because from the consumer side, in terms of stops, you're not interested in schemas.

309
00:26:56,060 --> 00:26:58,640
You're interested in the concrete scenario, right?

310
00:26:58,900 --> 00:27:00,160
I'm sending the request.

311
00:27:00,280 --> 00:27:02,980
I want a beer, but let's assume that I'm too old.

312
00:27:03,080 --> 00:27:06,720
So I should get a response that, Hey, you're told you're not going to get it.

313
00:27:06,720 --> 00:27:07,180
Right.

314
00:27:07,440 --> 00:27:12,460
So as a consumer, what, what is of your interest is a, is a scenario.

315
00:27:12,460 --> 00:27:24,700
So those, uh, contracts represents scenarios basically, but there's a nice thing that you mentioned that you said that, uh, and I agree with that, that the consumer sits with the producer and they agree on the contract.

316
00:27:24,940 --> 00:27:28,220
But the problem is that it sounds really waterfall, right?

317
00:27:28,220 --> 00:27:37,120
Like we sit down and we assume that this is the contract that we will, uh, we will want, which kind of is not the best way to go.

318
00:27:37,840 --> 00:27:41,140
Uh, so here comes the consumer driven contracts.

319
00:27:41,300 --> 00:27:42,440
What does it mean?

320
00:27:42,740 --> 00:27:55,880
It means that the consumer can sit down, write some codes on his side and let's say, play around with the contract of the producer offline.

321
00:27:56,220 --> 00:27:57,380
What does it mean?

322
00:27:57,780 --> 00:28:05,820
Let's say that the producer hasn't written a single line of code in terms of verifying if the person can get the beer, right?

323
00:28:05,940 --> 00:28:07,500
But let's say nothing is there.

324
00:28:08,280 --> 00:28:16,500
The consumer can still play around with the contracts offline, completely not even talking to the producer.

325
00:28:17,540 --> 00:28:21,360
And he, the, the, the consumer team can generate stubs locally.

326
00:28:21,700 --> 00:28:25,020
So you no longer guess what kind of an API you will need.

327
00:28:25,180 --> 00:28:30,700
You can actually do it because you will locally create the stubs.

328
00:28:31,340 --> 00:28:34,780
So imagine this, it's like doing TDD.

329
00:28:34,780 --> 00:28:39,360
So you write a code and you have a service that you will call.

330
00:28:39,580 --> 00:28:40,800
So what, what are you doing?

331
00:28:41,280 --> 00:28:44,520
You're creating an interface or you're stubbing an interface.

332
00:28:44,880 --> 00:28:47,560
And you say, I don't like what this interface does.

333
00:28:47,680 --> 00:28:50,340
So you change its behavior and then you change it again.

334
00:28:50,420 --> 00:28:51,580
You change it again until you're happy.

335
00:28:52,040 --> 00:28:58,880
And then, for example, you say to a friend that was working you in team, you know, I have a prototype of a, of an interface.

336
00:28:59,040 --> 00:29:03,080
Can you please like implement those, this interface?

337
00:29:03,220 --> 00:29:04,060
And he does it, right?

338
00:29:04,680 --> 00:29:08,160
So you can do the same with the API and the contracts.

339
00:29:08,260 --> 00:29:10,640
So you sit down, you play with the API.

340
00:29:11,100 --> 00:29:15,640
And then you say, for example, okay, this is the API that would be awesome.

341
00:29:16,520 --> 00:29:20,620
Let's go and talk to the producer team if they accept it or not, et cetera.

342
00:29:20,680 --> 00:29:22,120
You can do it, of course, iteratively.

343
00:29:22,260 --> 00:29:24,320
You don't have to like do it at once.

344
00:29:24,700 --> 00:29:31,400
But the best thing about this approach is that even though the other side hasn't written a single line of production code,

345
00:29:31,400 --> 00:29:35,700
you can still simulate that they have done it because you can work offline.

346
00:29:36,660 --> 00:29:46,920
So this is the like the consumer driven thing that the consumer is driving the change and you don't block.

347
00:29:47,460 --> 00:29:49,440
Like everything right now is reactive.

348
00:29:50,020 --> 00:29:57,340
So this, this process is also reactive, so to say, because the consumer can work offline.

349
00:29:57,580 --> 00:29:59,760
He can work on the contract.

350
00:29:59,940 --> 00:30:09,300
Then both sides have to block like on the agreeing on the contract and then both sides can work in parallel because they agreed on the contract.

351
00:30:09,920 --> 00:30:19,840
So the consumer can like finish up its work if there's still some like implementation to be done and the producer implements the missing feature.

352
00:30:20,860 --> 00:30:24,340
Yeah, no, and I think, I think, I think you're, you're hitting on it.

353
00:30:24,340 --> 00:30:25,360
It must be sent.

354
00:30:25,560 --> 00:30:29,400
Well, we're, we're discussing the snappy phrase for it, but it's almost like a,

355
00:30:29,400 --> 00:30:33,680
an inversion of control of how interfaces normally work, right?

356
00:30:33,780 --> 00:30:37,860
Like precisely that's a very good way to present it.

357
00:30:37,860 --> 00:30:41,740
The, the, the producers usually have all of the control over what it looks like.

358
00:30:41,840 --> 00:30:49,180
And, and, you know, I mean, this is this to exaggerate the point, to make the point, like when something breaks, it's not their fault.

359
00:30:49,860 --> 00:30:57,000
Whereas, whereas like in a consumer driven approach, it's the, the consumers are, are, I mean, tell me this is true,

360
00:30:57,060 --> 00:30:59,680
but the consumers are defining what the interface looks like.

361
00:31:00,120 --> 00:31:05,520
And, and in their, in their defining it, like maybe it's not totally the producer's fault.

362
00:31:05,520 --> 00:31:09,580
Like, and, and, and someone can always maliciously go in and be dumb, right?

363
00:31:09,580 --> 00:31:21,060
And do something, do something silly, but it's, it's, it's sort of like the, the relationship that's, that's put up here is it says consumers will come to you and tell you how they want to consume your service.

364
00:31:21,240 --> 00:31:34,200
And so it's, it's, it's, as a producer, it's your job to make sure that you can talk to them in the way they want to, instead of, instead of, uh, basically demanding the way that, uh, that, that consumers interface with your APIs and stuff.

365
00:31:35,060 --> 00:31:45,440
Precisely. Going further, in Spring Cloud Contract, an important problem is ownership of contracts. Who should own it? Where should it be placed?

366
00:31:47,080 --> 00:31:52,980
I'm in favor of actually the producer having the contract inside its repo.

367
00:31:53,780 --> 00:32:03,720
But there is another approach, because sometimes for security reasons, for example, the producer's code is hidden. You cannot even see it. You cannot access it.

368
00:32:04,220 --> 00:32:09,440
So there is another approach where all the contracts can lay in a single repo.

369
00:32:09,440 --> 00:32:15,020
Why would you even want that? For a very particular and nice reason.

370
00:32:16,620 --> 00:32:33,380
We are writing about this in the documentation, but if you, let's say, create this repo in a proper structure, in terms of folders and stuff like that, as a producer, you will know,

371
00:32:33,380 --> 00:32:37,520
for example, which consumers you broke with a change that you did locally.

372
00:32:38,600 --> 00:32:48,240
Why is it so? Because all of the consumers, like, to put it briefly, there is a root folder for a producer.

373
00:32:48,600 --> 00:32:51,600
Like, let's say, let's call him Foo, right?

374
00:32:51,720 --> 00:32:52,340
The Foo producer.

375
00:32:52,940 --> 00:32:59,640
So under the Foo folder, all the consumers will put their contracts, like, this is the expectations that we want to have.

376
00:33:00,160 --> 00:33:12,460
So, when the producer will generate the tests from those contracts, the producer will know exactly which contract from which consumer it was.

377
00:33:12,820 --> 00:33:17,900
So, in that case, breaking changes are close to impossible, right?

378
00:33:18,040 --> 00:33:21,280
Because they would have to be introduced by the consumers.

379
00:33:21,400 --> 00:33:26,480
The consumer would have to say, I explicitly want you to break the contract, right?

380
00:33:26,820 --> 00:33:36,180
But if, like, in that case, most often what companies do when they have the contracts in a single repo is that there is a reviewing process.

381
00:33:36,180 --> 00:33:37,720
You cannot just merge the PR.

382
00:33:37,920 --> 00:33:41,400
There has to be some, you know, plus ones or okays, something like that.

383
00:33:41,680 --> 00:33:45,020
So somebody would have to check and say, hey, you're breaking the backwards compatibility.

384
00:33:45,600 --> 00:33:52,600
But the great thing about this approach is that the producer will know exactly which consumer was broken.

385
00:33:53,260 --> 00:33:55,960
Of course, we're talking about a very abstract thing.

386
00:33:55,960 --> 00:34:02,020
So, I advise everybody to check out the Sprinklr contract documentation where we provide an example and stuff like that.

387
00:34:02,480 --> 00:34:06,820
But I hope that I've managed to explain that a little bit at least.

388
00:34:07,240 --> 00:34:15,560
But, you know, what you're hitting on there is like the, it sounds simple, is like the testing aspect of all of this, right?

389
00:34:15,680 --> 00:34:26,540
So, like, at the beginning, like, when you and I are talking, one of the main problems is testing large systems with lots of services in them is difficult.

390
00:34:26,900 --> 00:34:30,960
It's tedious and takes a long time for all sorts of reasons, right?

391
00:34:31,080 --> 00:34:39,160
And so one of the things to make testing easier, if you're using a whole bunch of different services, is to basically stub them out.

392
00:34:39,620 --> 00:34:46,740
And whether you want to call them, like, mock things or whatever, but essentially, to use yet another word, you're simulating all these other services.

393
00:34:46,880 --> 00:35:03,580
So if you have some application that uses, like, 50 different services, like your brewery thing, you know, there's another part of your brewery resource ERP application that I guess is, like, brewing the beer and trying to keep track of, like, this one's been brewing for five days, this one for eight.

394
00:35:03,740 --> 00:35:14,400
And then you would have another component that's like, we've committed to sell 50 kegs to this company, so we've got to make sure to allocate that and not sell 50 kegs to this other company.

395
00:35:14,540 --> 00:35:16,320
So you've got all these different services.

396
00:35:17,060 --> 00:35:24,960
And if you wanted to change, like, aspects of those, you would almost have to, like, deploy them to production to make sure everything integrated.

397
00:35:25,420 --> 00:35:25,820
Yeah, that's precise.

398
00:35:26,080 --> 00:35:29,020
That would be, you know, insanity, more or less.

399
00:35:29,420 --> 00:35:36,260
So instead, you have, like, simulations that run and stuff like that, you know, whatever you want to call them, ways of testing it to integrate it.

400
00:35:36,800 --> 00:35:40,940
So I've almost forgotten what I was saying here, but hopefully I'll remember.

401
00:35:40,940 --> 00:35:43,400
Most likely about feedback cycle.

402
00:35:43,500 --> 00:35:43,880
That's right.

403
00:35:43,880 --> 00:35:56,400
And then so the issue, one of the things that you're solving here in an interesting way is, like, so if I'm depending on those services and changes that are made to the services, testing them is annoying and it's hard to test them in the first place.

404
00:35:56,400 --> 00:36:02,500
So when you use the spring contracts, the first thing it does is generate a bunch of stubs for you.

405
00:36:02,980 --> 00:36:18,620
So you can, it may not test the, I don't know what you kids call it anymore nowadays, but it may not actually test the behavior of the service thoroughly, but it at least tests the semantics, I guess.

406
00:36:18,700 --> 00:36:21,640
It tests that, like, the language is English, so to speak.

407
00:36:21,820 --> 00:36:22,180
Exactly.

408
00:36:22,560 --> 00:36:25,840
And which is a huge thing to test.

409
00:36:25,840 --> 00:36:42,080
So you've got that on the consumer side and what's kind of intriguing about this approach, as you were just suggesting, is that so maybe what we should do is if on the producer side, they should proactively know when they're about to break some user of their code.

410
00:36:42,280 --> 00:36:54,940
So the users of their service will basically send them or it'll be auto-generated, but they will have a test suite, more or less, that simulates what all of the users of the service will be doing.

411
00:36:55,280 --> 00:37:07,280
So when the producer of the API makes changes, they can test if they're going to break things before it, I don't know, is checked in, so to speak, or before it reaches all of the various consumers of things, which...

412
00:37:07,280 --> 00:37:08,280
Yeah, so you're right.

413
00:37:08,280 --> 00:37:09,280
Yeah, so you're right.

414
00:37:09,280 --> 00:37:17,720
And actually, with Spring Cloud Contract, depending on where you have the, who is owning the contract, you'll have it in two different ways.

415
00:37:17,840 --> 00:37:32,280
If the producer is owning the contract, and the producer, for example, is doing the backwards incompatible change, the next time any consumer will be built, for example, you can put on your CI, like, cron for, I don't know, every 15 minutes or something like that.

416
00:37:32,840 --> 00:37:50,660
The build will break, because Spring Cloud Contract, on the consumer side, will download the latest stubs that are, right now, backwards incompatible, and your integration tests will reuse those backwards incompatible stubs, and they will blow up.

417
00:37:50,840 --> 00:37:51,840
Right?

418
00:37:51,840 --> 00:38:07,840
And if the ownership is in the common repo, actually, if you, let's say, merge the request for a backwards incompatible change of the API, the producer's tests will be broken.

419
00:38:07,840 --> 00:38:08,840
Because...

420
00:38:08,840 --> 00:38:09,840
Why is it so?

421
00:38:09,840 --> 00:38:12,840
Let's say that you have changed a URL from full to bar, right?

422
00:38:12,840 --> 00:38:17,840
It's a backwards incompatible change, because you deleted the full and you added a bar.

423
00:38:17,840 --> 00:38:24,840
And suddenly, auto-generated tests are run, and they are shooting at the bar endpoint, which doesn't exist.

424
00:38:24,840 --> 00:38:27,840
So, the producer code will blow up.

425
00:38:27,840 --> 00:38:29,840
As simple as that.

426
00:38:29,840 --> 00:38:30,840
Yeah.

427
00:38:30,840 --> 00:38:31,840
Now, that makes sense.

428
00:38:31,840 --> 00:38:38,840
And it's another good example of, like, how the onus for compatibility is placed on the producer.

429
00:38:38,840 --> 00:38:39,840
Yeah.

430
00:38:39,840 --> 00:38:41,840
I mean, it makes sense, right?

431
00:38:41,840 --> 00:38:43,840
Because these are producer stubs.

432
00:38:43,840 --> 00:38:48,840
So, we have to check if the contract is telling the truth against that producer.

433
00:38:48,840 --> 00:38:49,840
Hmm.

434
00:38:49,840 --> 00:38:50,840
Right, right, right.

435
00:38:50,840 --> 00:38:55,840
And so, maybe to get close to wrapping up a little bit.

436
00:38:55,840 --> 00:38:58,840
So, how, like, all of the...

437
00:38:58,840 --> 00:39:04,840
We mentioned Groovy, which is an actual technology that you can, you know, use a keyboard to do something with.

438
00:39:04,840 --> 00:39:08,840
But most everything we've talked about is sort of, like, theory and hand waviness.

439
00:39:08,840 --> 00:39:12,840
So, like, what does this end up looking like in Spring Cloud?

440
00:39:12,840 --> 00:39:13,840
Like, how does...

441
00:39:13,840 --> 00:39:15,840
What do the tools actually look like?

442
00:39:15,840 --> 00:39:16,840
Okay.

443
00:39:16,840 --> 00:39:18,840
So, that's a very good question.

444
00:39:18,840 --> 00:39:24,840
So, on the producer side, you create the...

445
00:39:24,840 --> 00:39:28,840
Not necessarily on the producer side, but let's skip it.

446
00:39:28,840 --> 00:39:30,840
Let's say, let's stay with this example.

447
00:39:30,840 --> 00:39:35,840
You create the Groovy based contracts.

448
00:39:35,840 --> 00:39:40,840
You're using the Spring Cloud contracts, like, jar.

449
00:39:40,840 --> 00:39:42,840
Like, the contents of the jar, right?

450
00:39:42,840 --> 00:39:43,840
To do it.

451
00:39:43,840 --> 00:39:54,840
You add a Maven or Gradle plugin that allows you to change the contract into the tests or change the contracts into a stub.

452
00:39:54,840 --> 00:39:56,840
So, that's on the producer side.

453
00:39:56,840 --> 00:40:04,840
On the consumer side, you are using Spring Cloud contract stub runner, which has quite a good name because it's running stubs.

454
00:40:04,840 --> 00:40:11,840
So, basically, when you add it, in your integration tests, you can provide an annotation, auto-configure stub runner,

455
00:40:11,840 --> 00:40:19,840
where you provide the group ID, artifact ID, and a bunch of other stuff of stubs that you want to be downloaded.

456
00:40:19,840 --> 00:40:28,840
So, automatically, when you run your tests, we are checking the nexus or artifactory that you have provided the URL to.

457
00:40:28,840 --> 00:40:35,840
We are searching for the stubs that you have provided, like, in the properties of the test.

458
00:40:35,840 --> 00:40:37,840
We're downloading those stubs.

459
00:40:37,840 --> 00:40:43,840
We're starting fake HTTP servers, and we're feeding those servers with stubs.

460
00:40:43,840 --> 00:40:52,840
So, basically, you don't have to do anything to start in-memory HTTP servers in your tests as a consumer.

461
00:40:52,840 --> 00:40:59,840
Another thing that we are doing is pretty much the same thing, but for messaging, because we were focused on HTTP.

462
00:40:59,840 --> 00:41:04,840
So, Spring Cloud contract gives you the very same approach with messaging.

463
00:41:04,840 --> 00:41:07,840
So, you create a contract in which you define a message.

464
00:41:07,840 --> 00:41:16,840
For example, if something happens, like, I don't know, if a scheduler is started, a message will be sent.

465
00:41:16,840 --> 00:41:24,840
So, on the producer side, if you put that in the contract, we will execute that scheduler that you mentioned,

466
00:41:24,840 --> 00:41:29,840
and we will check if, on that channel, a message was sent.

467
00:41:29,840 --> 00:41:35,840
So, if you're not doing that, we will find it out, and your build will break.

468
00:41:35,840 --> 00:41:42,840
And on the consumer side, you can say, I will not go into details how, but it's just an interface, so it's really easy to trigger.

469
00:41:42,840 --> 00:41:48,840
You can trigger the message, because with HTTP, it's simple, because you're sending a request, and you get the response, right?

470
00:41:48,840 --> 00:41:49,840
It's synchronous.

471
00:41:49,840 --> 00:41:53,840
But with messaging, you know, suddenly, you get the message.

472
00:41:53,840 --> 00:42:00,840
So, we give the tools to trigger that message, and what is awesome is that that message has been tested against the producer.

473
00:42:00,840 --> 00:42:02,840
So, the producer is not lying.

474
00:42:02,840 --> 00:42:07,840
So, basically, these are the two tools that we support.

475
00:42:07,840 --> 00:42:16,840
Oh, and another thing is that on the consumer side, we also support, we integrate with Spring Cloud, basically, which makes sense,

476
00:42:16,840 --> 00:42:21,840
because it's Spring Cloud contract, and we can stab out completely the service discovery.

477
00:42:21,840 --> 00:42:28,840
So, if you're using, for example, console, and you're using Spring Cloud contract, in your integration test, we don't care that it's console,

478
00:42:28,840 --> 00:42:30,840
because we're going to stab it out.

479
00:42:30,840 --> 00:42:32,840
It's going to be done completely in memory.

480
00:42:32,840 --> 00:42:41,840
So, we're going to start an HTTP server in memory, and when you're going to request for that using, for example, Fain,

481
00:42:41,840 --> 00:42:52,840
or, you know, some sort of discovery client, we will route it, the call, to that fake HTTP server that we have started.

482
00:42:52,840 --> 00:42:58,840
So, yeah, it's really fast, and you can completely stub out the discovery service.

483
00:42:58,840 --> 00:42:59,840
Yeah.

484
00:42:59,840 --> 00:43:00,840
That makes sense.

485
00:43:00,840 --> 00:43:06,840
So, like, how long does this kind of stuff take?

486
00:43:06,840 --> 00:43:08,840
Like, what are the units of work?

487
00:43:08,840 --> 00:43:11,840
Like, obviously, they're sort of like defining a contract, right?

488
00:43:11,840 --> 00:43:12,840
That's probably...

489
00:43:12,840 --> 00:43:14,840
Yeah, so I can actually go through the whole flow.

490
00:43:14,840 --> 00:43:15,840
Yeah, yeah, yeah.

491
00:43:15,840 --> 00:43:16,840
Yeah.

492
00:43:16,840 --> 00:43:18,840
So, it's consumer-driven contracts.

493
00:43:18,840 --> 00:43:19,840
So, the consumer starts.

494
00:43:19,840 --> 00:43:27,840
So, the consumer, by any means, regardless of whether the contracts are in a single repo or the producer side,

495
00:43:27,840 --> 00:43:30,840
the consumer starts with a TDD.

496
00:43:30,840 --> 00:43:39,840
He writes a test for the feature that he wants to do, and he plays around with the contract that is there locally,

497
00:43:39,840 --> 00:43:45,840
because he can work offline, play around with the contract until it suits the needs of the consumer, right?

498
00:43:45,840 --> 00:43:51,840
Once the consumer is done, like, the communication with the producer takes part,

499
00:43:51,840 --> 00:43:54,840
takes place that, you know, this is the contract that we want to have.

500
00:43:54,840 --> 00:43:55,840
So, this is the first part.

501
00:43:55,840 --> 00:43:59,840
So, the consumer plays around with the API until it's satisfied.

502
00:43:59,840 --> 00:44:05,840
Then, the producer can take the PR with the contract and implement the missing feature.

503
00:44:05,840 --> 00:44:12,840
Once it's done, it's merged into, like, this branch is merged, this PR is merged into master,

504
00:44:12,840 --> 00:44:22,840
which means that the auto-generated tests passed and stubs of the producer are placed into Nexus or, like, Artifactory.

505
00:44:22,840 --> 00:44:28,840
And the last bit is that the consumer can switch off the flag of working offline to working online,

506
00:44:28,840 --> 00:44:33,840
which means that the stubs will be downloaded from this Nexus or Artifactory.

507
00:44:33,840 --> 00:44:34,840
That's it.

508
00:44:34,840 --> 00:44:38,840
So, do people, like, fill out the stubs to mess with them?

509
00:44:38,840 --> 00:44:41,840
Or is it just, like, you never touch those because they're auto-generated

510
00:44:41,840 --> 00:44:43,840
and you're just going to create a bunch of problems?

511
00:44:43,840 --> 00:44:45,840
You never touch the stubs. You touch the contract.

512
00:44:45,840 --> 00:44:46,840
Ah, right, right, right.

513
00:44:46,840 --> 00:44:53,840
Because the stubs, as an implementation of the HTTP server stub, we're using WireMock.

514
00:44:53,840 --> 00:44:56,840
WireMock, in terms of stubs, uses JSON.

515
00:44:56,840 --> 00:45:05,840
If you ever need to do a JSON in a JSON, you want to, it's misery and pain.

516
00:45:05,840 --> 00:45:07,840
You want to, like, cry.

517
00:45:07,840 --> 00:45:08,840
Right.

518
00:45:08,840 --> 00:45:11,840
Try to escape all the signs properly.

519
00:45:11,840 --> 00:45:12,840
It's really tedious.

520
00:45:12,840 --> 00:45:14,840
So, we're doing that for the user.

521
00:45:14,840 --> 00:45:21,840
The user can use, you know, Groovy's map notation to create a nice JSON or a G string.

522
00:45:21,840 --> 00:45:26,840
So, no escaping of, you know, quotes or stuff like that has to take place.

523
00:45:26,840 --> 00:45:29,840
So, the consumer can play around with the DSL.

524
00:45:29,840 --> 00:45:32,840
There's another approach that Spring Cloud Contract gives you.

525
00:45:32,840 --> 00:45:39,840
If you don't like Groovy or DSLs, you can create the stub via the res docs.

526
00:45:39,840 --> 00:45:44,840
So, as a producer, you're writing tests using spring res docs.

527
00:45:44,840 --> 00:45:47,840
And you also say that, okay, this test passed.

528
00:45:47,840 --> 00:45:51,840
And by the way, can you please create a stub from this?

529
00:45:51,840 --> 00:45:56,840
So, here, you don't have auto-generated tests because there's no contract.

530
00:45:56,840 --> 00:46:01,840
But you can still achieve the same goal of creating a stub.

531
00:46:01,840 --> 00:46:02,840
And the rest is the same.

532
00:46:02,840 --> 00:46:06,840
So, the stubs will be packaged and you can push them into Nexus or something like that.

533
00:46:06,840 --> 00:46:07,840
Right.

534
00:46:07,840 --> 00:46:08,840
So, we give various options.

535
00:46:08,840 --> 00:46:13,840
So, then, like, where do people get this stuff?

536
00:46:13,840 --> 00:46:15,840
Like, how long has it been out?

537
00:46:15,840 --> 00:46:19,840
Or, like, give us some, like, project history and stuff.

538
00:46:19,840 --> 00:46:30,840
Project history is really interesting because Spring Cloud Contract has a predecessor, which is called Accurist.

539
00:46:30,840 --> 00:46:37,840
So, the Accurist project was started, if I remember correctly, two years ago.

540
00:46:37,840 --> 00:46:39,840
And it had two GA's.

541
00:46:39,840 --> 00:46:44,840
So, it has already been battle proven.

542
00:46:44,840 --> 00:46:46,840
And Spring Cloud Contract has been released.

543
00:46:46,840 --> 00:46:49,840
Let me check it because I don't really remember.

544
00:46:49,840 --> 00:46:50,840
Two weeks ago.

545
00:46:50,840 --> 00:46:54,840
So, the GA of the Spring Cloud Contract is two weeks.

546
00:46:54,840 --> 00:47:01,840
But it's based on the foundations of a project that had its GA.

547
00:47:01,840 --> 00:47:03,840
I can actually even check that.

548
00:47:03,840 --> 00:47:05,840
But some time ago.

549
00:47:05,840 --> 00:47:07,840
And it was battle proven, as I mentioned.

550
00:47:07,840 --> 00:47:11,840
And the release was June the 2nd.

551
00:47:11,840 --> 00:47:12,840
It was the second release.

552
00:47:12,840 --> 00:47:15,840
And the first one was...

553
00:47:15,840 --> 00:47:17,840
Yeah, let me find it.

554
00:47:17,840 --> 00:47:22,840
The first one was on the February 29th.

555
00:47:22,840 --> 00:47:24,840
Right, right.

556
00:47:24,840 --> 00:47:25,840
Well, that sounds...

557
00:47:25,840 --> 00:47:27,840
So, like...

558
00:47:27,840 --> 00:47:29,840
Oh, what was I gonna ask?

559
00:47:29,840 --> 00:47:30,840
Oh, I know.

560
00:47:30,840 --> 00:47:36,840
So, aside from Spring Cloud, are there other, like, frameworks or implementations out here?

561
00:47:36,840 --> 00:47:39,840
Like, what are other frameworks people use for this kind of stuff?

562
00:47:39,840 --> 00:47:40,840
Yes.

563
00:47:40,840 --> 00:47:44,840
Another framework there is is called PACT.

564
00:47:44,840 --> 00:47:48,840
It's also a solution.

565
00:47:48,840 --> 00:47:50,840
The difference is...

566
00:47:50,840 --> 00:47:54,840
The main difference is that PACT supports multiple languages.

567
00:47:54,840 --> 00:47:59,840
So, not only JVM stuff.

568
00:47:59,840 --> 00:48:02,840
It has a different approach toward...

569
00:48:02,840 --> 00:48:05,840
It also has something called, like, a broker.

570
00:48:05,840 --> 00:48:14,840
Where, let's say, this broker can tell you which service uses which contract and which version.

571
00:48:14,840 --> 00:48:17,840
You can check out their documentation to learn more.

572
00:48:17,840 --> 00:48:23,840
The main difference is that they don't auto-generate tests.

573
00:48:23,840 --> 00:48:32,840
And they don't have this stop-runner feature, so the stops are automatically, let's say, downloaded and started for your tests.

574
00:48:32,840 --> 00:48:37,840
But, yeah, they also favor this consumer-driven approach.

575
00:48:37,840 --> 00:48:42,840
And, yeah, that's basically another tool that I know.

576
00:48:42,840 --> 00:48:43,840
Yeah.

577
00:48:43,840 --> 00:48:44,840
Are there others?

578
00:48:44,840 --> 00:48:45,840
Maybe they are.

579
00:48:45,840 --> 00:48:50,840
Well, is there anything else you want to wangle in here before we wrap up?

580
00:48:50,840 --> 00:48:52,840
Or do you think we covered it sufficiently?

581
00:48:52,840 --> 00:49:01,840
So, like, hopefully we've managed to cover why would you like to consider doing consumer-driven contracts.

582
00:49:01,840 --> 00:49:05,840
I hope that we have emphasized what the problems we're trying to solve.

583
00:49:05,840 --> 00:49:16,840
So, basically, stop validity and reusability and how you can create a much nicer API using this approach.

584
00:49:16,840 --> 00:49:21,840
I hope that we've shown how you can do that with Spring Cloud contracts.

585
00:49:21,840 --> 00:49:25,840
It's difficult to talk about code instead of showing it.

586
00:49:25,840 --> 00:49:33,840
So, I encourage everybody to check out the Spring Cloud contract documentation.

587
00:49:33,840 --> 00:49:40,840
Also on my blog, TooMuchCoding.com, I think I've written quite a few things on this.

588
00:49:40,840 --> 00:49:50,840
So, yeah, hopefully we've managed to show light on a topic that is really old, so to say, but often very neglected.

589
00:49:50,840 --> 00:49:59,840
So, people redo their work and they have problems on some staging or test environments when they're doing end-to-end testing.

590
00:49:59,840 --> 00:50:02,840
Whereas they can have the feedback cycle, like, pushed back.

591
00:50:02,840 --> 00:50:10,840
So, they can already, during the build phase, see that their code is not working, which is the very idea of testing, right?

592
00:50:10,840 --> 00:50:11,840
Yeah.

593
00:50:11,840 --> 00:50:15,840
And I think to, like, monkey climb it up to, like, larger topics, right?

594
00:50:15,840 --> 00:50:17,840
Like, we've gone this long.

595
00:50:17,840 --> 00:50:24,840
I don't think you would ever use a word like this, but it's sort of like a way of doing governance in your application.

596
00:50:24,840 --> 00:50:31,840
Like, and it's, again, it's kind of a reversal of how people usually think of governance.

597
00:50:31,840 --> 00:50:39,840
It's almost, you know, not quite, but it's decentralizing it and moving a lot of the chance for governance.

598
00:50:39,840 --> 00:50:44,840
And governance is sort of useless unless there's a way of enforcing when something bad has happened, right?

599
00:50:44,840 --> 00:50:50,840
So, it brings a lot of the enforcement of governance down to the consumer level.

600
00:50:50,840 --> 00:50:51,840
That's the decentralizing part.

601
00:50:51,840 --> 00:50:59,840
And I think, you know, whether or not, like, you're all, like, microservices happy or things like that, you're going to have services in your applications.

602
00:50:59,840 --> 00:51:08,840
And it's good to not just, as they say, cowboy it, but you want to have a fair amount of governance in the service for all the reasons that we went over.

603
00:51:08,840 --> 00:51:12,840
And also, because, you know, the enterprise architects have to have something to do, right?

604
00:51:12,840 --> 00:51:13,840
Exactly.

605
00:51:13,840 --> 00:51:16,840
And actually, speaking of it, I wanted to talk about this.

606
00:51:16,840 --> 00:51:18,840
Often they want to know what's there.

607
00:51:18,840 --> 00:51:29,840
So, actually, using Spring Cloud Contract, what we can easily do is to create ASCII documentation of the contracts that your apps has.

608
00:51:29,840 --> 00:51:32,840
And there's a new issue for that already in Spring Cloud Contract.

609
00:51:32,840 --> 00:51:33,840
I created a spike.

610
00:51:33,840 --> 00:51:35,840
So, it's actually trivial to achieve.

611
00:51:35,840 --> 00:51:45,840
So, we can present in a nice format for all those business people, like, information about the API in a scenario way.

612
00:51:45,840 --> 00:51:48,840
Because this is most likely what they are interested in.

613
00:51:48,840 --> 00:51:50,840
How does the service work?

614
00:51:50,840 --> 00:51:59,840
And since the contracts represent scenarios, you can easily convert that into a nice documentation.

615
00:51:59,840 --> 00:52:00,840
Oh, yeah.

616
00:52:00,840 --> 00:52:01,840
That's a good point.

617
00:52:01,840 --> 00:52:10,840
You can do, it's a side effect, is you can basically do an inventory of all the stuff you have and who's using it.

618
00:52:10,840 --> 00:52:15,840
Which is always a delightfully impossible problem to completely solve.

619
00:52:15,840 --> 00:52:18,840
But at least you can have some good swipes at it.

620
00:52:18,840 --> 00:52:19,840
Exactly.

621
00:52:19,840 --> 00:52:26,840
And especially, I mean, it becomes even, it becomes near impossible to solve if things are moving really quickly.

622
00:52:26,840 --> 00:52:28,840
But, yeah, that's interesting.

623
00:52:28,840 --> 00:52:30,840
It gives you a better handle on doing that.

624
00:52:30,840 --> 00:52:31,840
Well, great.

625
00:52:31,840 --> 00:52:33,840
Well, you know, you've already mentioned it.

626
00:52:33,840 --> 00:52:38,840
Why don't you tell people where they can go to catch up with you more and follow more stuff that you're doing?

627
00:52:38,840 --> 00:52:39,840
Yeah.

628
00:52:39,840 --> 00:52:49,840
So, basically, you can go to my blog, TooMuchCoding.com, where you will be able to find my Twitter handle, which is very difficult to spell.

629
00:52:49,840 --> 00:52:58,840
So, you can check out the Spring Cloud Contract documentation on cloud.spring.io.

630
00:52:58,840 --> 00:52:59,840
I'm there on Gitter.

631
00:52:59,840 --> 00:53:02,840
So, you can check out the Spring Cloud Contract Gitter channel.

632
00:53:02,840 --> 00:53:08,840
I try to be really fast at solving issues.

633
00:53:08,840 --> 00:53:09,840
What else?

634
00:53:09,840 --> 00:53:10,840
I guess that's it.

635
00:53:10,840 --> 00:53:14,840
I mean, you can check some of the presentations of mine.

636
00:53:14,840 --> 00:53:18,840
I haven't yet put in the documentation the video about Spring Cloud Contract.

637
00:53:18,840 --> 00:53:21,840
But once there is one out there, I'm for sure going to put there.

638
00:53:21,840 --> 00:53:29,840
So, hopefully, it's going to also be more, like, give more explanations than the documentation as such.

639
00:53:29,840 --> 00:53:33,840
But we try to have the documentation be really practical.

640
00:53:33,840 --> 00:53:38,840
So, there are some use cases, like, step-by-step approach to consumer-driven contracts.

641
00:53:38,840 --> 00:53:46,840
So, hopefully, the documentation will be good enough for starters.

642
00:53:46,840 --> 00:53:47,840
Indeed.

643
00:53:47,840 --> 00:53:48,840
Well, great.

644
00:53:48,840 --> 00:53:50,840
Well, thanks for, you know, you actually suggested this topic.

645
00:53:50,840 --> 00:53:51,840
I think it was nice.

646
00:53:51,840 --> 00:53:52,840
So, thanks for suggesting that.

647
00:53:52,840 --> 00:53:56,840
And for the audience, thanks for listening into this.

648
00:53:56,840 --> 00:53:57,840
It's always good to have you.

649
00:53:57,840 --> 00:54:00,840
And this, as always, has been Pivotal Conversations.

650
00:54:00,840 --> 00:54:10,840
You can find our stuff over at pivotal.io/podcast or in our not-so-secret backend at soundcloud.com/pivotalconversations.

651
00:54:10,840 --> 00:54:20,840
Also, if you're feeling kind of sprightly or are insanely bored and want something to do, you should go over to iTunes and leave us a star rating or even write a review.

652
00:54:20,840 --> 00:54:21,840
That would be delightful.

653
00:54:21,840 --> 00:54:29,840
You know what you should do when you write a review is you should go write a review and, first of all, talk about how awesome this podcast is and how everyone should listen to it.

654
00:54:29,840 --> 00:54:38,840
But at the end, you should put on sort of tips for what enterprise architects should do with their time in sort of a cloud-native world.

655
00:54:38,840 --> 00:54:50,840
Or if you don't like that topic, just angle in a few lines on sort of either something that an enterprise architect has done that's awesome recently or a total boneheaded thing that an EA has done.

656
00:54:50,840 --> 00:54:57,840
And, you know, I find that it's good to have a little mission for a review write-up.

657
00:54:57,840 --> 00:54:59,840
Otherwise, you just talk about how awesome it is.

658
00:54:59,840 --> 00:55:02,840
But that's something that you can do as homework.

659
00:55:02,840 --> 00:55:04,840
And with that, we'll see everyone next time.

660
00:55:04,840 --> 00:55:05,840
Bye-bye.

661
00:55:05,840 --> 00:55:06,000
Bye.

662
00:55:06,620 --> 00:55:07,060
Bye.
