Hey team, may I ask did anyone use <Pact.io> in Pr...
# general
z
Hey team, may I ask did anyone use Pact.io in Provider-driven way, means Provider generate contract, then consumer always verify, does this approach make sense? or maybe overengineering comparing with schema validation? Thanks in advance
t
Kinda. Pact doesn’t support this directly. In Pact, a consumer is a synonym for client (which is not strictly true - it provides http requests, and consumes http responses). Some of the assumptions change if you were able to write a Pact test for a provider - for example, it’s not breaking if a consumer never calls an endpoint that is available.
The point of consumer-driven testing is that you only test what you need
so, in most http APIs, driving that from the server side doesn’t have that property
since, most http APIs provide a few different services. Mostly (but not always) they are dependencies of the clients - they are servers, but also they only exist to provide for the clients
in some cases, it might make sense to consider the client as a provider for the service - for example, in remote logging, or other situations where you don’t care too much what the response codes are.
I have built a contract testing tool which lets you do client or server-driven contracts. You can find that here: https://case.contract-testing.io/
it’s compatible with the pact broker
(but not compatible with Pact files)
A contract in this case is a series of request / response examples
z
Thanks a lot for swift and detailed reply!
t
There are some bullet points here on why it’s not the same as schema tests: https://case.contract-testing.io/docs/Alternatives/contract-testing-vs-schema
In general, I think it’s best practice to define the tests from the client, as that way you only cover what you actually need
If you define from the provider, you have to guess / unnecessarily cover parts you don’t actually need
z
in some cases of SDLC, we maybe have API-First driven approach, it means producers manage the schema creation, and build up the "contract"
in another hands, Consumer may don't fully understand/predict the usage properly
maybe I'm wrong? feel very free to correct me
t
we maybe have API-First driven approach,
This is very common. I also think it’s an industry wide anti-pattern (for the same reason - do you have a shop where the shopkeeper decides what the customers want? No, it would be better to ask the customers first, then buy those things)
manage the schema creation, and build up the “contract”
I wouldn’t call this a contract, at least from the perspective of contract testing
A contract is a series of examples
Anyway, it’s true that a lot of teams do their API definitions at the server side.
I think the testing tools should support this - even though I don’t think it’s the right way to do it
😀 1
(with contract tests, you could develop your services in a TDD way - where the consumer just writes tests for the calls it wants to make - this is a very efficient way to develop - but again, I realise most teams wouldn’t want to do that)
So, I built that ContractCase project I linked above. I’m afraid it only works at the moment if both sides are in javascript (or typescript), but support for other languages is under development
z
I realise most teams wouldn’t want to do that)
That's correct, in a big scale projects, the challenge is not technical, but the communication between consumers and providers. In terms of
ContractCase
, will it support Provider-driven contract test? if yes, may I ask what's the difference between Schema validation(imagine we ensure all API changes detect break schema changes) and
ContractCase
t
It already does
but it’s very much in beta
(imagine we ensure all API changes detect break schema changes)
I am imagining this and wondering how you do it
Every team I have heard say that they ensure this can’t happen has at least a few outages per year because of broken contracts
Schema validation misses whole classes of errors. We’ve written about this a lot
I’m just running out the door, but I can leave you a more detailed reply tomorrow
Matt wrote a blog post about it, let me link you
Schemas catch syntax errors - you know the parser won’t break, but will the message have any meaning to the other side? Who knows.
z
in terms of GRPC https://buf.build/docs/about/, the tool potentially can verify and block the break schema changes.
Copy code
Forwards and backwards compatibility is not enforced: While forwards and backwards compatibility is a promise of Protobuf, actually maintaining backwards-compatible Protobuf APIs isn't widely practiced, and is hard to enforce.
t
Consider:
Copy code
message UserTypeResponse {
  string userType = 1;
}
If a provider is updated to emit
"User"
,
"Admin"
and
"Moderator"
, but the consumer expects
"User"
and
"Admin"
that is a breaking communication change, but not a breaking protobuf change. Any automated tooling aimed at detecting breaking changes in protobuf will not see this
Similarly, if the consumer expects
user
moderator
and
admin
“but that’s a bad protobuf, and you shouldn’t use it like that” Sure, I agree. But, people will. I prefer an automated tool that will catch this
z
imagine above case, consume only can handle
user
,
admin
, but not
moderator
, in this case, we maybe just miss a unit test/integration test to cover
else
status to check if there is a unknown type. but however if producer decided only to emit
admin
and
moderator
, but remove
user
, schema validation is passed, and it won't impact the consumer's functionality, but maybe a feature is gone completely. in this case, more or less, Contract test seems is protecting the "data" between the consumer and producer.
t
In that example, yes. I would say that generally it is testing the communication between them.
It’s not a breaking change to remove an endpoint no one is using
Or a field no one is relying on
schema validation is passed, and it won’t impact the consumer’s functionality, but maybe a feature is gone completely.
You can’t tell whether it will or won’t impact the consumer’s functionality from the schema alone
That’s the advantage of the contract test. The contract includes “this is the response I need”
I really do have to go. Feel free to leave questions and I (or someone else) will answer them later
z
Thanks a lot @Timothy Jones!
💯 1
m
One way I have thought making this flow work, would be for a provider to generate and ship the pact tests (or perhaps even just a pact file) with the SDK or client. The client would then need to produce a pact file that is equivalent or a subset of the given pact (assuming it’s not necessarily easy to re-use the tests themselves). If this were true, you’d have better confidence there are no compatibility issues.
💯 1
b
I think a workflow like that might help bootstrap new consumers. It's a lot like the "test consumer" pattern I have historically used to TDD from the API side, so a PoC could be made before the consumer started in earnest.
yes party 1
t
Yeah. With tools to chop and change contract files that would be really easy. Of course, those tools don’t exist yet (at least for any framework that I know)
m
The hard part is being able to compare two pact files that have the same structure, but different matchers - as the semantics on those comparisons get difficult. But you could imagine starting with a simpler version where that is disallowed, and then basic utilities to splice and dice a pact file would be chefkiss