I've been using Pact (pact-js) for GraphQL contrac...
# general
a
I've been using Pact (pact-js) for GraphQL contracts between client apps and Apollo GraphQL servers, by using pact-js on the client side and server verification tests that allow pact to check the GraphQL response meets contract expectations. Now I'm looking at moving to Apollo Federation, and trying to figure out whether pact could still be used in this context. In a federated architecture there is an single API Gateway sitting in front of multiple subgraphs, responsible for composing the schemas from those subgraphs into one unified supergraph that is consumed by client applications. Each subgraph is a separately versioned deployable component (as is the gateway itself), but from the client perspective the behaviour of the GraphQL server is the same as in the non-federated case. In the non-federated case, the GraphQL server is a single versioned (consumer) pacticipant in this case. In the federated case however, the gateway itself is a relatively thin component whose source version rarely changes, and each subgraph is more like a non-federated server with its own version history. When a contract between a client and the gateway is verified, this is in effect saying that N (where N is the number of subgraphs) "sub-contracts" between the client and each subgraph are verified i.e. can-i-deploy for the client depends on the versions of all the subgraphs used to service the query. As client requests will typically span multiple subgraphs, defining contracts between clients and subgraphs isn't the right approach; the contract should be between the client and the supergraph. It feels like this would be quite a technical challenge - from the client perspective there is one contract, but from the provider perspective there are multiple contracts because each provider (subgraph) has a role to play in servicing the query. There isn't a single deployable versioned component that can take the role of the provider here because the gateway itself isn't changing when the subgraphs change, unless one invents some pseudo-deployable supergraph pacticipant whose version depends in some way on the versions of all contributing subgraphs but is never really deployed, just recorded in the pact broker as such. I'd be interested in any thoughts on this; it feels quite complex to manage and use, but maybe I have missed something.
t
I feel like this design is going to cause complexity whether or not you use pact... but
Pact versions assume a single "deployable". What you could do is front multiple versions as one deployable
do verification of the gateway at version X, with A, B, C beyond it, and treat that all as one provider "version"
it'll work, and you'll get the contract safety, but now you will have some of the disadvantages of integration tests
a
Thanks @Timothy Jones - yes it feels like having a pseudo-provider that is versioned as a logical aggregation of gateway + subgraphs is the inevitable conclusion; I'm just not sure the effort and cognitive complexity for developers is repaid by the benefit, which is a shame as GraphQL pacts against a single monolithic server are super-easy to do.
t
A good thought experiment you can try to help unpack this is - how would I be sure it's safe to deploy without pact?
if you find that it's hard to reason about what is deployed where, and what you should test against, then you'll find a challenge with or without pact - and the design might need some re-thinking
a
I think in this case there is some overlap between the checks and balances around deployment provided by Apollo Managed Federation and that provided by a CDC solution; its a matter of trying to figure out what each solution brings that the other doesn't.
t
I don't know if it would help, but you could also trivially publish the contract repeatedly - so each backend service would see the same contract
a
I don't think it would in this case alas; each backend subgraph would in general not be able to handle the contract, because the GraphQL request would contain elements that the subgraph knew nothing about.
👍 1
.. but thanks for your advice; I think its confirmed for me what would need to be done. The only question now is the cost/benefit analysis, so I'll plug away at that for a while.
t
You can also consider a contract between the client and the gateway, and then between the gateway and each provider. But I think that will make you do work that GraphQL Federation is supposed to do
Let us know if you come up with a good solution!
a
Yes exactly - I'd have to figure out the federated server query plan and use that to drive gateway-subgraph contracts, but it feels like the wrong bit of the flow for me to be testing to be honest. Will do!
💯 1