Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback for “Schemas and Types”; Why is a "Query" considered a "type"? #1825

Open
dperiwal opened this issue Nov 15, 2024 · 3 comments
Open

Comments

@dperiwal
Copy link

dperiwal commented Nov 15, 2024

It is more of a fundamental question in terms of naming some artifacts of a GraphQl system.

Why is a "Query" considered a "type"? It is hard for me to conceptualize the following two declarations in the same specification because their essential nature and semantics are different:

type Character {
name: String!
appearsIn: [Episode!]!
}

type Query {
droid(id: ID!): Droid
}

Character describes the type (composition) of a data object whereas Query is an operation. Conceptually, Query, Mutation, and Subscription are "operations" - not "types".

Why are we overloading the term "type" to specify the "composition of a data object" as well as an "operation"?

Saying the following may be more appropriate if we have to use the term "type":

objectType Character {
name: String!
appearsIn: [Episode!]!
}

operationType Query {
droid(id: ID!): Droid
}

Maybe you can explain it in a way that avoids this conceptual confusion between the "composition of a data object" and an "operation" indicated by the same term "type".

@dperiwal
Copy link
Author

Alternatively,

type Character {
name: String!
appearsIn: [Episode!]!
}

operation Query {
droid(id: ID!): Droid
}

@benjie
Copy link
Member

benjie commented Nov 15, 2024

The reason that the Query, Mutation and Subscription types are considered object types, is because they are object types. They are defined in exactly the same way, they operate in exactly the same way, and they can be referenced in the same way (it's common to reference the query root operation type in mutation operation payloads for example - though I can't think of a valid situation for referencing the mutation root operation type anywhere). You can even name them whatever you want, for example in the SWAPI schema we call the query root operation type Root instead of Query. If you name these root operation types non-standard names (or want a type with these names to not be interpreted as root operation types) then you must explicitly select the root operation types via the schema keyword:

# This is the `query` root operation type
type Root {
  randomVirus: Virus
}

type Virus {
  name: String!
  knownMutations: [Mutation]
}

# This is NOT the `mutation` root operation type, as defined below
# this schema does not support the `mutation` operation type.
type Mutation {
  name: String!
}

schema {
  query: Root
}

Here's the relevant part of the GraphQL specification if you're inclined to read further:

https://spec.graphql.org/draft/#sec-Root-Operation-Types

@benjie
Copy link
Member

benjie commented Nov 15, 2024

Another way to think about it is in terms of graph traversal (see my blog post on this topic) - the Query type effectively represents the "node" in the graph with which you start traversal, and then you traverse from there using its fields in the same way that you would any other "node" in your GraphQL query.

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

No branches or pull requests

2 participants