Kumar Harsh Technical writer and software developer based in India.

Using aliases in GraphQL

5 min read 1534

Using Aliases GraphQL

If you’ve used GraphQL for your production application, you may have encountered a scenario where you needed your custom queries to return custom field names. Or, maybe you received two query results in the same server response, causing the field names to clash.

In these situations, we can use GraphQL aliases to improve our queries. In this tutorial, we’ll cover what an alias is, how it works, and when we should use it. We’ll look into several scenarios and expand on this concept with a relevant example. Let’s get started!

What are GraphQL aliases?

Aliases allow us to rename the data that is returned in a query’s results. Aliases don’t change the original schema, instead, they manipulate the structure of the query result that is fetched from your database, displaying it according to your specifications.

Aliases come in handy when you want to improve the efficiency of your queries. For example, let’s say you are trying to fetch the same data by applying various filters. Many developers would be inclined to write separate queries and execute them in independent API calls. In this situation and others, aliases can help you optimize and improve the organization of your queries.

There are several scenarios where you may want to change the name of the field where you receive query results. Let’s take a look at two different examples.

Fetching multiple objects in one query

Using aliases, you can combine multiple fetches on the same object in a single GraphQL query.

Let’s say you are building an app that displays a list of posts in a feed. A typical post in your app would look like the code block below:

type Post {
  id: string
  parent: string
  type: string # POST or COMMENT
  author: string
  title: string
  text: string
  createdAt: string
}

For simplicity, we’re limiting ourselves to only the string data type for each field. Ideally, you would use an enum for the type field and a custom Date scalar for the createdAt field.

We made a custom demo for .
No really. Click here to check it out.

Note that we defined a type field to accommodate different types of posts in the same table. In our case, we have posts and comments.

A query for getPosts would look like the following code block:

query getPosts {
  posts {
    id
    parent
    type
    author
    title
    text
    createdAt
  }
}

Now, let’s say you have a post and a comment in your database. If you run the query above, you’ll get a response similar to the code block below:

{
  "data": {
    "posts": [
      {
        "id": "s9d8fhsd-fsdf",
        "parent": null,
        "type": "POST",
        "author": "Korg",
        "title": "Let's start a revolution",
        "text": "Hey, man. I'm Korg. We're gonna get outta here on that big spaceship. Wanna come?",
        "createdAt": "11:06 AM IST, Aug 7 2021"
      },
      {
        "id": "d8g6dffd-jfod",
        "parent": "s9d8fhsd-fsdf",
        "type": "COMMENT",
        "author": "Loki",
        "title": null,
        "text": "Well, it seems that you are in dire need of leadership.",
        "createdAt": "11:09 AM IST, Aug 7 2021"
      }
    ]
  }
}

Your database might also contain a long line of posts and comments like in the example above. You might try to write a query that fetches the posts in a separated list of posts and comments:

query getPosts {
  posts(type: "POST") {
    id
    author
    title
    text
    createdAt
  }
  posts(type: "COMMENT") {
    id
    parent
    author
    text
    createdAt
  }
}

However, you’ll realize that the query doesn’t run at all, and it throws the following error:

{
  "errors": [
    {
      "message": "Fields 'posts' conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.",
      "locations": [
        {
          "line": 2,
          "column": 3
        },
        {
          "line": 9,
          "column": 3
        }
      ]
    }
  ]
}

When executed, the query returns two lists of results for the same field name posts. Using aliases, we can change the field name to two different keywords, causing the query to run flawlessly:

query getPosts {
  posts: posts(type: "POST") {
    id
    author
    title
    text
    createdAt
  }
  comments: posts(type: "COMMENT") {
    id
    parent
    author
    text
    createdAt
  }
}

Now, you can easily make multiple fetch calls in the same GraphQL query, saving network usage and decreasing code complexity.

Adding meaning to your query results

A self-explanatory name makes it easy for any developer to understand your code well. The same is true for database results. You need to ensure that developers handling API responses are well-versed in what the data means. Let’s learn how to add meaning to our query results to help provide useful naming conventions.

Let’s reconsider our earlier example. Our schema looks like the following code block:

type Post {
  id: string
  type: string # POST or COMMENT
  author: string
  title: string
  text: string
  createdAt: string
}

The schema contains a parent field that is meant to link a comment to a post, defining which post is the parent of a comment. While this should make sense to a database engineer, it might not be clear to a frontend engineer right away.

In this case, you can structure your traditional query to better describe the parent property:

query getPosts {
  posts {
    id
    parentPost: parent
    type
    author
    title
    text
    createdAt
  }
}

You can rename other properties as you wish. In the results returned after executing the query, the original names will be entirely overwritten. A typical response will look like the following code block:

{
  "data": {
    "posts": [
      {
        "id": "s9d8fhsd-fsdf",
        "parentPost": null,
        "type": "POST",
        "author": "Korg",
        "title": "Let's start a revolution",
        "text": "Hey, man. I'm Korg. We're gonna get outta here on that big spaceship. Wanna come?",
        "createdAt": "11:06 AM IST, Aug 7 2021"
      },
      {
        "id": "d8g6dffd-jfod",
        "parentPost": "s9d8fhsd-fsdf",
        "type": "COMMENT",
        "author": "Loki",
        "title": null,
        "text": "Well, it seems that you are in dire need of leadership.",
        "createdAt": "11:09 AM IST, Aug 7 2021"
      }
    ]
  }
}

GraphQL alias best practices

While implementing an alias in GraphQL is fairly straightforward, improper use can wreak havoc on your application. To optimize the results of the GraphQL alias, be sure to keep the following points in mind.

Self-explanatory naming

Because aliases allow you to alter your results’ field names, it is important to ensure that the names you choose make sense with respect to the actual data.

Although it is tempting to choose a convenient, short name that you can easily understand, you must also consider that other developers may work on the project after you. Unless your naming conventions are self-explanatory, they may have a hard time understanding your code, potentially causing errors in your project.

For example, the code below contains an example of a poorly-named alias:

query getPosts {
  p: posts(type: "POST") {
    id
    author
    title
    text
    createdAt
  }
  c: posts(type: "COMMENT") {
    id
    parent
    author
    text
    createdAt
  }
}

It may seem convenient to name the two intermediate query results p for posts and c for comments, however, let’s take a look at the results of the above query:

{
  "data": {
    "p": [
      {
        "id": "s9d8fhsd-fsdf",
        "author": "Korg",
        "title": "Let's start a revolution",
        "text": "Hey, man. I'm Korg. We're gonna get outta here on that big spaceship. Wanna come?",
        "createdAt": "11:06 AM IST, Aug 7 2021"
      },
    ],
    "c": [
      {
        "id": "d8g6dffd-jfod",
        "parent": "s9d8fhsd-fsdf",
        "author": "Loki",
        "text": "Well, it seems that you are in dire need of leadership.",
        "createdAt": "11:09 AM IST, Aug 7 2021"
      }
    ]
  }
}

As you can see, without contextual information about the type of the results, it is difficult to understand what p and c mean. Therefore, sticking with the full names posts and comments would be a better alternative in this scenario.

Use aliases only when needed

An alias is just a pseudonym for an existing field, so it might be tempting to use them even when they are not necessarily needed. However, renaming can lead to unnecessary mappings in your code. For example, let’s take our getPosts query as an example:

query getPosts {
  posts {
    id
    parent
    type
    author
    title
    text
    createdAt
  }
}

Each field in the posts definition is self-explanatory. However, you may want to add an even stronger descriptor for each field, as below:

query getPosts {
  posts {
    postId: id
    parentPost: parent
    postType: type
    author
    title
    postContent: text
    createdAt
  }
}

Keep in mind that with each renaming, you’ll need to propagate the new name everywhere in your code. Before adding an alias, you should consider the usefulness of the additional detail. I recommend only using aliases when it solves a recurring problem.

Make server-side changes

If you find yourself repeatedly renaming the same fields, you may want to consider dropping the alias and renaming the field on the server itself. Similarly, if you have to use aliases frequently on your client, you may need to reduce your database schema.

Aliases are meant to be a handy fix for renaming things quickly, however, you should not rely on them heavily. If you find yourself using aliases often, there may be an issue with your server-side naming conventions. In this case, using aliases will only further complicate the codebase.

Conclusion

Aliases are a great way to reorganize your GraphQL query results. Aliases are especially helpful when your backend data model and frontend data specifications don’t exactly fit together and you need to align them manually.

In cases when you need to fetch multiple query results on the same source at one time, aliases are mandatory. However, it is also essential to use aliases sparingly. While aliases are mostly harmless and only change the data after it is returned, unnecessary use can cause confusion about the data’s schema and even result in bugs.

I hope you enjoyed this tutorial!

Monitor failed and slow GraphQL requests in production

While GraphQL has some features for debugging requests and responses, making sure GraphQL reliably serves resources to your production app is where things get tougher. If you’re interested in ensuring network requests to the backend or third party services are successful, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Kumar Harsh Technical writer and software developer based in India.

Testing accessibility with Storybook

One big challenge when building a component library is prioritizing accessibility. Accessibility is usually seen as one of those “nice-to-have” features, and unfortunately, we’re...
Laura Carballo
4 min read

Leave a Reply