Skip to content

Conversation

@bbakerman
Copy link
Member

@bbakerman bbakerman commented Sep 24, 2021

Previously there was no way to "sort" the complete ordering that a schema would be printed in.

The SchemaPrinter code would choose an ordering for part of this process even though some of the output (non types) was ordered via graphql.schema.GraphqlTypeComparatorRegistry

This PR allows the SchemaPrinter to order all of the elements according to the provided graphql.schema.GraphqlTypeComparatorRegistry

It has a default one that preserves the old behavior.... modulo one thing - directive definitions are now sorted in name order (just like object types and so on are) where as before it was not.

The previous SchemaPrinter ordering was sensible - however the way it was implemented meant there was not way to replace it with a new order. This retains the sensible ordering BUT also allows a new ordering to be instituted

private Class<? extends GraphQLSchemaElement> elementType;

private GraphqlTypeComparatorEnvironment(Class<? extends GraphQLSchemaElement> parentType, Class<? extends GraphQLSchemaElement> elementType) {
Assert.assertNotNull(elementType, () -> "elementType can't be null");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be relaxed because now we can have a GraphqlTypeComparatorEnvironment where there is only a parent type and not element type.

This was probably wrong in the oder code but because we never sorted the top level types we never noticed this.

List<GraphQLSchemaElement> elements = directivesAndTypes
.map(e -> (GraphQLSchemaElement) e)
.filter(options.getIncludeSchemaElement())
.sorted(comparator)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The crux of the code that now allows the top level types to be sorted

}

private TypePrinter<GraphQLScalarType> scalarPrinter() {
private SchemaElementPrinter<GraphQLScalarType> scalarPrinter() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SchemaElementPrinter is more correct because we top level types and GraphQLDirectives to be printed

.elementType(GraphQLEnumValueDefinition.class)
.build();
Comparator<? super GraphQLSchemaElement> comparator = options.comparatorRegistry.getComparator(environment);
Comparator<? super GraphQLSchemaElement> comparator = getComparator(GraphQLEnumType.class, GraphQLEnumValueDefinition.class);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made this repeated code go into a common method

hello: String! @auth
}
"""
'''
Copy link
Member Author

@bbakerman bbakerman Sep 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directives are now sorted by name like all the other types were, hence this change to the test

newEnvironment()
]
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we relaxed a non null rule

"Skipped when true."
if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
result == '''directive @argDirective on ARGUMENT_DEFINITION
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directives are now sorted by name like all the other types were, hence this change to the test - same in most of the directive tests. They are now sorted by directive name just like the other types were

'''

}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we can have our own comparator on all types and it respects it

@bbakerman bbakerman changed the title This puts in the ability to sort a schema during printing The ability to sort a schema during printing Sep 24, 2021
@bbakerman bbakerman added this to the 18.0 milestone Sep 24, 2021
…nting

# Conflicts:
#	src/test/groovy/graphql/Issue2141.groovy
…der_schema_printing

Compatator is used for in order schema printing
// This sensible order was taken from the original SchemaPrinter code. It ordered the types in this manner
private static final ImmutableMap<Class<? extends GraphQLSchemaElement>, Integer> SENSIBLE_ORDER =
ImmutableMap.<Class<? extends GraphQLSchemaElement>, Integer>builder()
.put(GraphQLDirective.class, 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't specify unfortunately how "schema { query: Foo ..}" element will be printed.

@andimarek andimarek merged commit c9f6ea7 into master Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants