GraphQL Core: Arguments, Aliases & Variables #7
Deep dive into the GraphQL Arguments, Aliases & Variables and how to work with them
In this tutorial, you'll learn in detail about Core concepts of GraphQL. In this post, we will look into below concepts
Arguments
Aliases
Operation Name
Variables
If the only thing we could do was traverse objects and their fields, GraphQL would already be a very useful language for data fetching. But when you add the ability to pass arguments to fields, things get much more interesting.
{
person (id:1) {
name
image
id
height
}
}
In a system like REST, you can only pass a single set of arguments - the query parameters and URL segments in your request. But in GraphQL, every field and the nested object can get its own set of arguments, making GraphQL a complete replacement for making multiple API fetches.
You can even pass arguments into scalar fields, to implement data transformations once on the server, instead of on every client separately.
{
person (id:1) {
name
image
id
height(unit: FOOT)
}
}
Arguments can be of many different types. In the above example, we have used an Enumeration type, which represents one of a finite set of options (in this case, units of length, either METER or FOOT).
GraphQL comes with a default set of types, but a GraphQL server can also declare its own custom types, as long as they can be serialized into your transport format.
If you have a sharp eye, you may have noticed that, since the result object fields match the name of the field in the query but don't include arguments, you can't directly query for the same field with different arguments.
That's why you need aliases - they let you rename the result of a field to anything you want.
{
empireHero: person(id: 1) {
name
image
id
height
}
jediHero: person(id: 1) {
name
image
id
height
}
}
You can try changing the alias name in below playground:
In the above example, the two person fields would have conflicted, but since we can alias them to different names, we can get both results in one request.
Up until now, we have been using a shorthand syntax where we omit both the query keyword and the query name, but in production apps it's useful to use these to make our code less ambiguous.
Here’s an example that includes the keyword query as operation type and HeroNameAndFriends as operation name :
query HeroNameAndFriends {
person(id: 1) {
name
image
id
height
}
}
The operation type is either query, mutation, or subscription and describes what type of operation you're intending to do. The operation type is required unless you're using the query shorthand syntax, in which case you can't supply a name or variable definitions for your operation.
The operation name is a meaningful and explicit name for your operation. It is only required in multi-operation documents, but its use is encouraged because it is very helpful for debugging and server-side logging.
When something goes wrong (you see errors either in your network logs, or in the logs of your GraphQL server) it is easier to identify a query in your codebase by name instead of trying to decipher the contents.
So far, we have been writing all of our arguments inside the query string. But in most applications, the arguments to fields will be dynamic: For example, there might be a dropdown that lets you select which Star Wars episode you are interested in, or a search field, or a set of filters.
When we start working with variables, we need to do three things:
Replace the static value in the query with $PersonInput
Declare $person as one of the variables accepted by the query
Pass person: value in the separate, transport-specific (usually JSON) variables dictionary
# variable input type to accept input from user
input PersonInput {
name: String!
age: Int
}
# actual graphql query vith variable input
mutation ($person: PersonInput) {
createPerson(person: $person) {
name
age
id
}
}
# Query Variables
{
"person": {
"name": "Mike",
"age": 34
}
}
Here's what it looks like all together, at the bottom of the editor, click on the Query Variable tab to edit variables passed to the query :
Now, in our client code, we can simply pass a different variable rather than needing to construct an entirely new query. This is also in general a good practice for denoting which arguments in our query are expected to be dynamic - we should never be doing string interpolation to construct queries from user-supplied values.
All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type matches on the server. Learn more about input object types on the Schema page.
Default values can also be assigned to the variables in the query by adding the default value after the type declaration.
mutation ($person: PersonInput = { name: "Mike", age: 34} ) {
createPerson(person: $person) {
name
age
id
}
}
When default values are provided for all variables, you can call the query without passing any variables. If any variables are passed as part of the variables dictionary, they will override the defaults.
In the next tutorial, we will look into Directives & Fragments.