Hi! We had a few questions regarding the new bi-di...
# general
w
Hi! We had a few questions regarding the new bi-directional contract feature of Pactflow (and I suppose Pact in general). 1. To our understanding, Pact is great for direct service to service contract enforcement, but what happens when you add an API gateway into the equation where a service needs to go through the gateway before reaching the microservice? Ideally the gateway would not contain much, if any business logic and mostly functions as a passthrough for api calls in our system. The documentation says it simplifies things, but how is unclear. 2. The documentation here recommends not using Pact for a BFF pattern. However, it's unclear if this documentation is meant to apply just to consumer driven contract testing or if it also applies to the bi-directional contracts as well. Could you clarify that as well? In a nutshell, this is the problem we're trying to understand in the following diagram. If using the bi-directional contract feature, where should Pact live (if at all)? • (2) only? ◦ It's clear the microservice is the provider, but who is the consumer? Technically the client, but with the gateway proxying/transforming data potentially, does the consumer contract live here? • (1) + (2)? ◦ Given the uncertainties of (2) alone, does it make sense the chain the contracts? Probably not, but wanted to validate this. • (3) only? ◦ For contract testing purposes, act as if the gateway doesn't exist and just have the contract between the true consumer/provider? • (4) We have something wrong with our contract testing approach entirely and if so, what should be the approach.
👋 1
y
I was pondering the same question today, when chatting to a friend. re: point 2 - this recommendation about Pact not for BFF/API Gateway patterns, relates to the traditional Pact consumer driven contract model, where the provider verification interacts directly with a provider codebase. I think a few people have been wondering about how the traditional CDCT (consumer driven) and BDCT (bi directional) contract testing approaches would work together. If the api gateway was purely non transformational, I would probably use BDCT between 1/2 and use a flavour of a non HTTP CDCT verification at point 3
What you really need is a "non-HTTP" pact between your consumer and the downstream system. Check out this gist for an example of how to use the Pact contract generation and matching code to test non-HTTP communications.
I don't have good examples of that in use, bar the linked gist. I love where this train of thought is going, and I also 😍 the fact you made a diagram! I really want to showcase some ways Pact (both BDCT and CDCT) can work or not work with API gateways/BFF's and module federation
🙌 2
w
Thanks for quick response and yes, that helps clarify a lot of things! We figured we can't be the only ones using an API gateway, so more documentation for BDCT and CDCT with gateways in the future would be great!
y
Hope to hear more real world experiences and share them, so keen to hear what our community has to say 🙂 We used them extensively in a previous project, some as transformational, some pass through, all to access on prem systems, but never got round to properly covering them with Pact because we had far bigger testing challenges in the org
w
This is perhaps more of a Pactflow question then, but if we did (1) and (2) above, that would make the api gateway the consumer and provider (as it should be). Would a pact broker visual the network diagram for the full sequence between the client, gateway and microservice? Or would it just show as two separate contracts where it'll be client to gateway and then gateway to microservice? Or alternatively if we chose to just implement (2), how simple would it be to rename the "consumer" [api gateway]?
m
If the gateway was basically pass-through, I’d simply add a single contract (3). Sometimes the gateway adds or validates headers that don’t pass downstream. In this case, i’d still do the above, and test this in other ways (usually, this is such a core part of the API it will be caught in several other places if not fully tested via CT anyway). If the gateway starts to change the paths / routes, you could go either way. If the gateway did things like orchestrate/choreograph and stitch multiple APIs together, then you need to treat them as separate tests. BDCT can make some of these situations simpler, primarily because they can be tested in a black-box way unlike with Pact which requires you to write unit tests, which can often be quite cumbersome depending on the API gateway technology. For example, Axway/Apigee/Layer7 and the like are basically not unit testable, which makes Pact hard to use. But BDCT can side step some of these technical barriers because you have more ways to test it at arms length.
r
I’m also really curious to hear your thoughts on this. I just went through @Matt (pactflow.io / pact-js / pact-go)’s video on BDCT and was hoping to hear more about how to handle the case where a gateway stitches multiple APIs together. What we have done to solve this problem is split our CDCT into two: one between the consumer and the gateway and another between the gateway itself and the provider. This has worked but has been challenging to maintain (the setup is a lot more complex than I’m making it out to be). Is this something Pactflow supports already? And if not is it in your roadmap? How would you solve this challenge?
m
What technology is your gateway Rafael?
and how does it stitch it all together - configuration? Code? (something else?)
r
It is a NodeJS GraphGL Gateway built on top of Apollo that combines schemas from multiples services into a federated schema. Is that the information you were after, @Matt (pactflow.io / pact-js / pact-go)?
m
Yes, thanks
OK, so I just did an export of the slack workspace public channel data, and it’s now up at docs.pact.io/slack
🙌 1
Checkout the #C0135EDRC4R channel and also this archive of a discussion about federation: https://docs.pact.io/slack/graphql.html#1599007978.023800
Keen on your thoughts
but, to be clear, whilst we would love to, we don’t have any concrete ideas/plans to make GraphQL better in this specific sense. Feedback and feature requests (pact.canny.io) would help of course
r
Ha! I work for the same company, so we are talking about the same setup there 🙂 I couldn’t find this discussion as I was limited to the history slack provided, but thanks for sharing. I’ll go through the messages and get back to you in a bit
😆 2
m
LOL
OK, well that’s funny. Hopefully we’ll be able to upgrade the workspace to Pro soon (SmartBear have indicated they might do this), so would mean I wouldn’t need to keep running the export to the site.
r
What I can say is that the approach we are using works, but it is more time consuming than when you only have to worry about a single consumer <-> provider pair. It also can misbehave when we have multiple concurrent deployments happening at the same time, as it becomes tricky to set on an exact gateway version to verify against.
I don’t exactly know how Pact could make this flow more seamless either 😞
m
I think it could possibly be solved by BDCT: 1. Consumer - write contract tests (whether using Pact or not), potentially usinsg a GraphQL plugin when the plugin framework is available 2. Gateway - Apollo federation presents a unified graphql schema and uploads to Pactflow (again, would need GraphQL BDCT support - this should be doable though) 3. API Providers - I’d need to know a bit more about how federation works, but potentially Pact works OK here already, if they are HTTP clients?
r
Re #3, yes, they are HTTP clients in our case. How would the Gateway in this case be able to validate requests though? It would need the providers, right?
m
In BDCT we only look at the schemas. If the graphql schema is sound we can compare to the consumer contract and be confident they are compatible. This assumes of course there are good ways to test the graphql schema + federation setup
👍 1