GraphQL is well-known for its easy to maintain backward-compatibility of APIs defined with it. You're supposed to just add new fields/types every time you need them and never remove old ones, only mark them with @deprecated directive. Thus, your server could evolve independently of its clients versions.
However, I have a quite opposite problem: we have many independent servers, some of which could not be updated ever, and client (potentially) could connect to anyone of them. Thus, when client adopts new fields in API types, that were introduced in some newer server, and then it connects to the older one, it will get the error, because it will try to query fields that do not exist on that server.
So the question is: is there some known approach on how to handle this type of situation in GraphQL?
The only thing I came up with is to have a top-level query field, that will return a list of supported types, as a string list. Thus, whenever you want to add a new filed in the existing type foo, you just add a new type foo2 and add this type to the list of supported types. Thus the client could decide what types it can use and, accordingly, what features it could show. However, this looks quite scary due to, well, graph nature of GraphQL: it is very hard to guaranty that clinet's query won't get to some unsupported type via some quirky path.
The other solution is, of course, just version the whole API and treat any change to schema as incompatible API version. But this looks, well, either too stiff, or too laborious to maintain.
P.S. I suppose, that, maybe GraphQL is just not a good solution for this type of situations, but, as usually happens, we decided to go with GraphQL far before we could foresee these use-cases.