graphql-java
graphql-java copied to clipboard
Fields returned in introspection query are ordered alphabetically and do not preserve "declaration" order
When upgrading from GraphQL-Java 11.0
to 12.0
I noticed the fields in the introspection query are suddenly ordered alphabetically.
Before they were ordered in the "natural" (declaration) order they were defined in the schema, which I would prefer.
Especially with tools like GraphiQL and Prisma Playground I would like a certain / "natural" (declaration) order of my fields. E.g. first start with the id
field, and not with e.g. a field alternate_email
(because it starts with an a
).
Probably related to #1314.
Probably related to #1314.
Not probably related - definitely related
as I said then
I agree with you that a stable introspection system is a win. I have started some PRs to try and address this.
The graphql spec says nothing about a stable order when a type is asked for its fields (althought query results must be stable) and graphql-js itself just uses Object js map behavior which is also not stable.
However in terms of debuggability and predictability a stable order is important. Out SchemaPrinter already does name sorting for stability reasons. I think the graphql types themselves should give out elements in a stable manner
So I get your concerns (eg id first) but they are other competing concerns and stable ordering is the best way we think to be sensible in the face of competing concerns
Preserving "declaration syntax" is a tax on the code we are not willing to have.
We won't be changing this
Thx for confirming @bbakerman
I understand the issue regarding stable order and I respect the choices made in graphql-java
.
One of the great things about GraphQL is the schema and the documentation that can be provided with it. I know companies where internal business analyst are using GraphiQL instead of a dedicated business apps - and they depend on the documentation from the introspection. It's a pity that fields are mixed up then...
PS: I also looked in the GraphQL spec and it does not explicitly mention the order.
However https://graphql.github.io/graphql-spec/June2018/#sec-Introspection mentions:
A GraphQL server supports introspection over its schema. This schema is queried using GraphQL itself, creating a powerful platform for tool‐building.
Take an example query for a trivial app. In this case there is a User type with three fields: id, name, and birthday.
For example, given a server with the following type definition:
type User {
id: String
name: String
birthday: Date
}
The query
{
__type(name: "User") {
name
fields {
name
type {
name
}
}
}
}
would return
{
"__type": {
"name": "User",
"fields": [
{
"name": "id",
"type": { "name": "String" }
},
{
"name": "name",
"type": { "name": "String" }
},
{
"name": "birthday",
"type": { "name": "Date" }
},
]
}
}
The example does preserve the declaration order.
The graphql spec says nothing about a stable order when a type is asked for its fields (althought query results must be stable) and graphql-js itself just uses Object js map behavior which is also not stable.
I did some tests with graphql-js
and ordering seems stable.
E.g. with:
import express from 'express';
import graphqlHTTP from '../src/';
import { buildSchema } from 'graphql';
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
users: [User]
hello: String
}
type User {
id: String
name: String
birthday: String
}
`);
// The root provides a resolver function for each API endpoint
var root = {
hello: () => 'Hello world!',
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000);
console.log('Running a GraphQL API server at http://localhost:4000/graphql');
The order in the introspection query is exactly what I would expect. And if shuffle the fields in the schema, the changes are reflected in the results of the introspection query.