Graphql-js: Lexographically sorted printSchema for comparison/diff stability?

Created on 6 Jul 2017  路  4Comments  路  Source: graphql/graphql-js

printSchema already sorts the type names alphabetically:

https://github.com/graphql/graphql-js/blob/ff4338daadb7f86e0d0700faff086dd46cbfb7b2/src/utilities/schemaPrinter.js#L74

It would also be useful for diffing if fields, arguments, enum values and various other entities were also sorted alphabetically. I have performed some local modifications and it seems the changes required are quite minor. However, I believe it's possibly the case that a schema sorted in one way is not identical to a schema sorted in another because the order of fields/arguments may affect the order in which they are resolved?

I therefore have the following questions:

  1. Would ordering the printSchema alphabetically by default be an acceptable change?
  2. If not, would it be acceptable to add a second argument added to printSchema that supports an enumeration of sort modes (e.g. 'natural' for the current ordering, 'alphabetic', and even something more exotic like ordering by heirarchy as in #281)?
  3. Would you accept a pull request to add these changes?

_Keywords (to help others find this issue, also detailing what I searched for before): alphabetic, lexographic, lexical, order, sort, printSchema, print, stable_

Most helpful comment

@leebyron I'm already working on utility function to sort the result of introspection query.
I will try to submit PR in a next few days.

All 4 comments

It seems this has already been attempted in #889 and since reverted in #920 because the relation s = parse(print(s)) didn't hold.

For anyone who needs this functionality for whatever reason; here's an ugly hack to tide you over, currently it sorts fields, args and enums via duck-typing:

const { parse, buildASTSchema } = require("graphql");
const { printSchema } = require("graphql/utilities");

const printSchemaOrdered = originalSchema => {
  // Clone schema so we don't damage anything
  const schema = buildASTSchema(parse(printSchema(originalSchema)));

  const typeMap = schema.getTypeMap();
  Object.keys(typeMap).forEach(name => {
    const Type = typeMap[name];

    // Object?
    if (Type.getFields) {
      const fields = Type.getFields();
      const keys = Object.keys(fields).sort();
      keys.forEach(key => {
        const value = fields[key];

        // Move the key to the end of the object
        delete fields[key];
        fields[key] = value;

        // Sort args
        if (value.args) {
          value.args.sort((a, b) => a.name.localeCompare(b.name));
        }
      });
    }

    // Enum?
    if (Type.getValues) {
      Type.getValues().sort((a, b) => a.name.localeCompare(b.name));
    }
  });

  return printSchema(schema);
};

The order of fields and arguments is often meaningful. I don't think such a feature should be part of printSchema, however a lexographicSortSchema function would be useful which returns a new Schema instance - that would be far more flexible and allow for printing the sorted schema or doing anything else you can do with a schema.

Feel free to send a PR if you're still interested, though I'm closing this issue for repo maintenance.

@leebyron I'm already working on utility function to sort the result of introspection query.
I will try to submit PR in a next few days.

Was this page helpful?
0 / 5 - 0 ratings