Hi guys, we are currently POC'ing PACT for our org...
# general
s
Hi guys, we are currently POC'ing PACT for our organization and have a conceptual question. Let's say we have a consumer, Checkout API and a provider, availability API. I as a consumer know, that the availability API is calling another Shipping API synchronously in order to deliver a meaningful response. Now the consumer and provider have aligned verbally that, if the Shipping 3rd party dependency is facing timeout or downtime, we as a consumer still expect a valid response. Now we as a small team that is building the POC ask ourselves, is this a test case we should portray as a PACT or not. E.g. with JVM syntax, I could write:
Copy code
.given("product with stock availability")
.given("transport API being down")
.uponReceiving("A request on /product-availability endpoint")
.willRespondWith()
            .status(200)
            .body(aValidResponseBodyUsingLikeEverywhere())
One part of our group says this is a valid test case, because we've made our verbal contract "On outage of your Transport API dependency we still expect a valid response from you" explicit now. On the other hand the second part of our POC group says, this is an implementation detail and we should not even know, that the provider is using a "transport api" to do its job. Are there any best practices on such an example?
👀 1
y
Interesting, my initial gut feel is that I would want to know that my consumer receives a valid response, when something goes wrong in the provider side (being agnostic of exactly what implementation detail) so you want a consumer product with stock, but your provider isn't healthy (because own x reasons). What should the consumer get when a downstream service is unavailable? A cached item? A valid response body? what is a valid response body? it could be that you expect an error, and your client handles that error. You might agree a timeout with your provider to say that if their downstream doesn't respond in 20 seconds, they return a response. We have done that at a previous client, as the api gateway window was 29 seconds and downstreams (multiple) could take much longer, or not respond. so after 25 seconds our provider would return a REFER response (it was a loan decision platform). Polling would then take place outside of that, to query the provider to retrieve a response returned from the downstream for their initial request. Sometimes this would result in the call having failed, due to a client issue (bad data in their submission) or a server side error, where-ever it was.
j
My opinion: If you don't expect the response in that case to be any different (no headers to indicate it's using cached data, body is the same) then it feels like an implementation detail you could test within the provider itself. But if your stated contract includes telling the consumer there's something going on and they may have to behave differently, it makes much more sense to have as a pact test so the consumer can validate the differences.
s
In case the provider faces timeout to transport api, the provider is falling back to a simpler logic and responds us „fallback: true“ next to their regular same response body. We could validate that, and we could validate that we „only“ expect 200 OK to explicitly make clear to the provider that we have a contract (200 OK with same response than usual). Because in case one day they would break that contract and respond 5xx without speaking to their consumers first, at least for checkout this is then a big problem (effectively a downtime).
m
If the contract changes based on availability of downstream systems, I think it’s perfectly OK to capture that in the contract. The inclusion of the name of the downstream system/systems is something for discussion for the reasons highlighted (does this link an implementation details). Is it possible for that to be generalised such as
.given("a downstream system is unavailable")
?
s
Hey Matt, thanks for replying. I think that sounds reasonable and is actually a great idea.
👍 1