No upgrade path from SchemaSyntaxSerializer and DocumentWriter to "new schema printer" in HotChocolate 12.4 to 12.5+
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
Related to https://github.com/ChilliCream/hotchocolate/issues/5145
That issue was closed before it was fully addressed. We still need documentation or an upgrade guide on how to switch from the SchemaSyntaxSerializer and DocumentWriter to the "new schema printer".
Our issue with the breaking change isn't how to get the schema as is suggested in Related to https://github.com/ChilliCream/hotchocolate/issues/5145 (we're already calling schema.ToString()), our issue is that we use both the SchemaSyntaxSerializer and DocumentWriter and they no longer exist after HotChocolate version 12.5+. Specifically, we have a _Service endpoint that we use for Apollo Federation. In order to get the schema that this endpoint returns, we have a class that inherits from the SchemaSyntaxSerializer and overrides various VisitXDefinition functions, and then we use those overridden functions to skip certain parts of the schema from being visited.
What we use is something like this:
public string Serialize(ISchema schema)
{
var schemaBuilder = new StringBuilder();
using (var writer = new StringWriter(schemaBuilder))
using (var documentWriter = new DocumentWriter(writer))
{
DocumentNode node = SchemaSerializer.SerializeSchema(schema);
_walker.Visit(node, documentWriter);
}
return schemaBuilder.ToString().Trim();
}
the _walker class above is the one that's using the SchemaSyntaxSerializer, and it uses it for methods like this:
protected override void VisitDirectiveDefinition(DirectiveDefinitionNode node, DocumentWriter writer)
{
if (!IsFederationDirective(node))
{
base.VisitDirectiveDefinition(node, writer);
}
}
The only thing we have to go off of for upgrading is a message that says "This is replaced by the new schema printer". As far as we can tell, there's no documentation on how to transition from the SchemaSyntaxSerializer and DocumentWriter to that new schema printer though, or even how to use the new schema printer in general. Is there any documentation you can provide for that?
Steps to reproduce
- Use the SchemaSyntaxSerializer type in v12.4.1
- Upgrade to a later version of 12.5+
- Compilation fails because the types are gone
Relevant log output
No response
Additional Context?
No response
Product
Hot Chocolate
Version
12.4.1
Why don't you use the HotChocolate.ApolloFederation package?
FederationSchemaPrinter: https://github.com/ChilliCream/hotchocolate/blob/main-version-12/src/HotChocolate/ApolloFederation/src/ApolloFederation/FederationSchemaPrinter.cs
Is the federation package a solution for you? It implements all the features of Apollo Federation V1.
Initially because we didn't know that class existed. The documentation for it we were referencing is unfinished https://chillicream.com/docs/hotchocolate/api-reference/apollo-federation and so we didn't know the preferred replacement
Looking into the FederationSchemaPrinter.cs file, it doesn't look like it fulfills the needs that the old SchemaSyntaxSerializer did. The only public method in the FederationSchemaPrinter is public static string Print(ISchema schema), which is returning a string instead of the DocumentNode. On top of that, the line we're using DocumentNode node = SchemaSerializer.SerializeSchema(schema); still works fine and I believe is doing the same thing as what's exposed in the new FederationSchemaPrinter.
The part we really need is an equivalent to the SchemaSyntaxSerializer and its .Visit() function. We're using that to stop certain nodes from being visited so we can keep them out of the schema. We can't use the defaults because of changes between HotChocolate 10 and HotChocolate 11/12 that broke our federated graph. One of these was the addition of the @stream, @defer, and @export directives. We're using the override for VisitDirectiveDefinition() to exclude those directives so we can ignore them and not break our schema.
Does a replacement for this .Visit() function exist?
These directives are not printed with the federation printer, look here: https://github.com/ChilliCream/hotchocolate/blob/f3db1202c8fc893d2cafd8b9cd993c55492daca2/src/HotChocolate/ApolloFederation/src/ApolloFederation/FederationSchemaPrinter.cs#L22
alternatively:
You can use this helper class and use the PrintSchema method:
https://github.com/ChilliCream/hotchocolate/blob/ef0015b30aa459270508b7cc1b7d23c75237666f/src/HotChocolate/Core/src/Types/SchemaPrinter.cs#L97
I think we should actually create a ToDocument helper method in ISchema that gives you the schema as a SDL AST.
Anyway, this method actually does exactly that.
Second thing you need is a visitor which you can find here: https://github.com/ChilliCream/hotchocolate/tree/main-version-12/src/HotChocolate/Language/src/Language.Visitors
with version 13 we are phasing out the initial legacy visitors that we used with V10 and will only support the ones above.
There are three types:
- SyntaxVisitor
- SyntaxWalker
- SyntaxRewriter (V13)
I will do a YouTube video on these soon, https://youtube.chillicream.com
If you need more help putting these things together hit me up on https://slack.chillicream.com
Ideally I must say it should be plug and play with the apollo federation package ... if not we should fix the issues that you have with it there.
ah, I had missed that those directives weren't included in what comes out of the FederatedSchemaPrinter. In that case I'll spend some time trying to get one of our services switched over to use that, see if the generated schema is the same as what we're currently generating, and report back here.
For that second option you mentioned involving the visitor, is there a particular class we're supposed to inherit from for that? I see a lot of Visitor and Walker classes but am not clear what, if anything, we'd need to extend for that solution
Closing this issue since FederatedSchemaPrinter already makes sure that the defer directive is not exposed.
@michaelstaib this shouldn't be closed yet, I haven't had a chance to confirm that it was working, but I have a window to investigate it now
Ideally, we'd be able to switch the DocumentWriter and SchemaSyntaxSerializer that no longer exist to use the FederationSchemaPrinter. I looked at the 12.6.2 code to find how it was used in the tests, but after trying to do the same in our resolver it seems to not be accessible

How are you supposed to be calling this if not directly? Or is the idea that if we set up our app to use the HotChocolate.ApolloFederation package then it would automatically have a schema sdl endpoint to produce the schema we're looking for? (and that I could compare against our current one to see if they're the same?). If it has to be all-or-nothing, that's gonna make it difficult to test as I'd have to refactor our entire app in order to use the new apollo stuff. Since this should just be a minor version upgrade, and we don't want to refactor our whole code base for multiple apps/services, does the DocumentNode PrintSchema stuff you mentioned above accomplish what my original code example was doing? And is there more documentation on that?