When a request has a content-encoding header set to gzip and a gzipped request body the Pact server would decompress the body and validate the request body according to the expectations set by the test.
The request is rejected by Pact. The request body is not decompressed and therefore does not match the request body expectations set by the test.
Make any request with a gzipped json request body to a Pact mock server.
How would you expect the expected body to be serialized in the pact?
This topic triggered a solid debate in my team, opinions are divided into two camps:
Pact treats Content-Encoding as a transport concern
The idea here is that things like Content-Encoding are a message transport concern and are not considered part of the contract. So Pact should support receiving compressed request bodies from consumers and compressed response bodies from providers but the Content-Encoding header is excluded from the Pact file and the relevant body is saved uncompressed. Comparisons could be drawn with the header "Connection: keep-alive" which today Pact currently ignores as far as validation goes.
Pact considers Content-Encoding as part of the contract
The idea here is that not all servers support Content-Encoding and so this should be treated as part of the contract. So when Pact is replaying requests it should aim to do this in a way that matches as close as possible to how the original consumer made the request. How you encode this information into the Pact file should be decided by what makes this easiest to implement in the Pact libraries.
I don't think content encodings should ever be part of the contract. The contract should be valid regardless if the server compresses the payload or not.
@BenSayers I tend to agree with @uglyog. The purpose of Pact is to test the data contract, not the transport. If you want to make sure that your transport works with encoding, you can use a simple unit test to make sure this works correctly.
I don't think a unit test would achieve the desired goal, however, I also lean towards the opinion that contract testing is about the messages rather than the mechanism. Canary/smoke tests/using the service in real life will pick up a misconfiguration in compression configuration, and it's unlikely to change once implemented.
Does whether the response is compressed/decompressed change any code in the consumer? Or is this generally abstracted by HTTP libraries?
The answer depends on the http library being used.
In the specific code we are writing now that caused us to run into this issue we are doing the compression of the request body in our consumer code as we were unable to find a library that handled the compression along with all our other requirements.
More generally we've found decompressing response bodies is more widely supported in http libraries compared to compressing request bodies.
I don't have a strong opinion on either option, I see merits in both. The option that doesn't require any changes to the pact specification is significantly lower cost to implement and roll out incrementally in all the pact libraries so that would be the deciding factor for me.
I'm going to close this one off. I think the community has spoken (or rather, by not speaking has indicated perhaps it's not an issue for the general populace).
Happy to pick this up again in the future.
Most helpful comment
This topic triggered a solid debate in my team, opinions are divided into two camps:
Pact treats Content-Encoding as a transport concern
The idea here is that things like Content-Encoding are a message transport concern and are not considered part of the contract. So Pact should support receiving compressed request bodies from consumers and compressed response bodies from providers but the Content-Encoding header is excluded from the Pact file and the relevant body is saved uncompressed. Comparisons could be drawn with the header "Connection: keep-alive" which today Pact currently ignores as far as validation goes.
Pact considers Content-Encoding as part of the contract
The idea here is that not all servers support Content-Encoding and so this should be treated as part of the contract. So when Pact is replaying requests it should aim to do this in a way that matches as close as possible to how the original consumer made the request. How you encode this information into the Pact file should be decided by what makes this easiest to implement in the Pact libraries.