Customising and Aliasing GraphQL Fields with Hasura
It is important to distinguish what it means to customise names of fields at the server side and GraphQL aliasing at the client side. Hasura has support for customising names of root fields and column fields.
Try it out on Hasura Cloud and read the docs to get started!
Client Side Aliasing with GraphQL Aliases
GraphQL Aliases let you rename the result of a field to anything you want. Consider the table users
with fields id
, full_name
, email_addr
, created_at
and updated_at
. Let's look at the anatomy of a simple query to understand this better. For example:
query getUsers {
users {
id
full_name
email_addr
}
}
There are 3 parts to the above query:
- operation type -
query
- operation name -
getUsers
- selection set -
id
,full_name
,email_addr
The response structure of the above query would look like:
{
"data": {
"users": [
{
"id": "3ea1352a-6654-444d-9357-62816ccbd2b3",
"full_name": "Praveen",
"email_addr": "[email protected]"
}
]
}
}
Now let's say, you want to map the response fields to UI elements directly and not deal with any transformations on the frontend. Ideally you would like the response from server to come in that format to achieve this. This can be done with GraphQL Aliases. You can alias the selection set to names of your choice.
We most likely want to replace verbose or vague fields with simple and readable fields for the UI.
Now the query can be written like below and the response format will match the keys you intended to be.
# Query
query {
users {
id
name: full_name
email: email_addr
}
}
# Response
{
"data": {
"users": [
{
"id": "3ea1352a-6654-444d-9357-62816ccbd2b3",
"name": "Praveen",
"email": "[email protected]"
}
]
}
}
Of course the above example is basic. But in certain cases, Aliases are necessary for the query to work. For example, if you have more than one top level field in the same query with different arguments, then you need to alias it. For example:
# Query with different arguments
query {
users(order_by: {created_at: desc}) {
id
name: full_name
email: email_addr
}
users(order_by: {created_at: asc}) {
id
name: full_name
email: email_addr
}
}
# Response is an error
{
"errors": [
{
"extensions": {
"path": "$.selectionSet",
"code": "validation-failed"
},
"message": "cannot merge fields with different arguments under the same alias: \"users\""
}
]
}
The above query doesn't work because we are using different arguments for the same top level field called users
. (Note the different order_by
object). Now for this to work, we need to make use of Aliases. The above query can be rewritten in the following format with alias for atleast one or both for it to work.
query {
usersByDesc: users(order_by: {created_at: desc}) {
id
name: full_name
email: email_addr
}
usersByAsc: users(order_by: {created_at: asc}) {
id
name: full_name
email: email_addr
}
}
GraphQL Aliases are dynamic, written on the client making the request. But as you can see, this is a workaround for use cases where you want the selection set to be named more readable. It is not prudent to write this for every query from every client making this request for modifying trivial fields.
Server Side Customisation with Hasura
Hasura lets you customise the field names at the server side. The tables and the columns created in Postgres can be customised to have a different name that can be used while querying. For example, the default root field names generated for a table named users
are:
Queries/Subscriptions:
users
users_by_pk
users_aggregate
Mutations:
insert_users
delete_users
update_users
The above root fields and the names of the column fields can now be customized. In Console, you can head to the Modify tab of the corresponding table under Data. For example, we can now change the field name of email_addr
to email
so that clients can now query without aliasing on the frontend.
So the following query should work after customising both the email_addr
and full_name
fields with Hasura.
query {
users {
id
name
email
}
}
Do note that, once you customise the fields to have a different name, you can no longer make the query with the original field names that you used before the customisation. Please ensure that your client apps are in sync with this change as once you begin using custom names, requests with the original field names will result in an error.
Now you can use your favorite naming conventions like camelCase or snake_case without worrying about the underlying postgres schema.