GraphQL In .NET Core Web API With Entity Framework Core - Part Five

GraphQL In .NET Core Web API With Entity Framework Core - Part Five

So far, we have seen GraphQL queries on a single table, multiple tables, and query with parameters in this article series.

Today, we will discuss the below items in detail.

  1. Aliases
  2. Multiple Queries
  3. Fragment
  4. Named Queries
  5. Variables
  6. Directive
  7. Optional Parameter

Aliases

Consider a scenario where you have exposed your APIs using GraphQL to multiple clients. Let’s take our existing example that we are going to expose - employee entity with certifications via API to multiple clients. Now each client wants their own naming convention for properties in an entity. One client may ask that I should get a certificate as a response; not the title. The other client may expect CertificationName as a response rather than a title, so we can’t create client specific APIs. In this situation, GraphQL alias feature will help. We need to ask the client to send alias along with the query, i.e., whatever the name they want, they just need to pass in the query and GraphQL will return the response accordingly.

In the below sample query, we have passed Employee as an alias for employee and CertificationName as the alias for title.

image.png

We can compare query and query response with alias and without alias for better understanding.

Query / AliasWithout AliasWith Alias
Query{ employees{ name certifications { title } } }{ Employee:employees{ name certifications { CertificationName:title } } }
Query Response{ "data": { "employees": [ { "name": "Akshay", "certifications": [ { "title": "MCSD" } ] }, { "name": "Panth", "certifications": [ { "title": "Scrum Master" } ] } ] } }{ "data": { "Employee": [ { "name": "Akshay", "certifications": [ { "CertificationName": "MCSD" } ] }, { "name": "Panth", "certifications": [ { "CertificationName": "Scrum Master" } ] } ] } }

Multiple Queries

In some scenarios, you want to execute more than one query and expect the result as single json, you can do the same by giving an alias. I have given aliases like E1 & E2 and written two different queries, one to fetch employee1 and another to fetch employee2 and you can see in the response that both the employees are added in the single JSON file.

image.png

Query

{  
  E1:employee(id:1){name certifications {title}}  
  E2:employee(id:2){name certifications {title}}  
}

Query Response

{  
  "data": {  
    "E1": {  
      "name": "Akshay",  
      "certifications": [  
        {  
          "title": "MCSD"  
        },  
        {  
          "title": "Scrum Master"  
        }  
      ]  
    },  
    "E2": {  
      "name": "Panth",  
      "certifications": [  
        {  
          "title": "MCT"  
        },  
        {  
          "title": "PMP"  
        }  
      ]  
    }  
  }  
}

Fragment

In multiple queries, if you observe closely, we have added {name certifications {title}} which we want as a response, we have written multiple times. Now, assume that you want to write similar kinds of queries around 10 or 20 times, then you need to write the same in the query that many times. In order to avoid such repetitions, we can use fragment. You can write fragment on type; i.e., EmployeeType, and define what you want as a response once, and pass the same fragment in each query with three dots (…) as a prefix and you will get the same response.

image.png

Query

{  
  E1:employee(id:1){...employeeList}  
  E2:employee(id:2){...employeeList}  
}  

fragment employeeList on EmployeeType{  
  name, certifications {title}  
}

Query Response

{  
  "data": {  
    "E1": {  
      "name": "Akshay",  
      "certifications": [  
        {  
          "title": "MCSD"  
        },  
        {  
          "title": "Scrum Master"  
        }  
      ]  
    },  
    "E2": {  
      "name": "Panth",  
      "certifications": [  
        {  
          "title": "MCT"  
        },  
        {  
          "title": "PMP"  
        }  
      ]  
    }  
  }  
}

Named Queries

Now in the case where you want to write required queries and execute as and when it's required, you can write named queries, which means give the name of each query so that while executing it will ask which one you want to execute. Refer to the the below screen shot for the reference. The syntax for this is query {queryName} followed by {Actual Query}

image.png

Query

query all  
{  
  employees {name certifications {title}}  
}  
query E1  
{  
  E1:employee(id:1){name, certifications {title}}  
}

Query Response for ‘all’

{  
  "data": {  
    "employees": [  
      {  
        "name": "Akshay",  
        "certifications": [  
          {  
            "title": "MCSD"  
          },  
          {  
            "title": "Scrum Master"  
          }  
        ]  
      },  
      {  
        "name": "Panth",  
        "certifications": [  
          {  
            "title": "MCT"  
          },  
          {  
            "title": "PMP"  
          }  
        ]  
      }  
    ]  
  }  
}

Query Response for ‘E1’

{  
  "data": {  
    "E1": {  
      "name": "Akshay",  
      "certifications": [  
        {  
          "title": "MCSD"  
        },  
        {  
          "title": "Scrum Master"  
        }  
      ]  
    }  
  }  
}

Syntax to call Named Queries from Postman

URLlocalhost:44332/graphql
MethodPOST
HeaderApplication/json

Request Body

{  
"query":"query all  
                {  
                  employees {name certifications {title}}  
                }  
         query E1  
                {  
                  E1:employee(id:1){name, certifications {title}}  
                }",  
"OperationName":"all"  
}

Response

{  
    "data": {  
        "employees": [  
            {  
                "name": "Akshay",  
                "certifications": [  
                    {  
                        "title": "MCSD"  
                    },  
                    {  
                        "title": "Scrum Master"  
                    }  
                ]  
            },  
            {  
                "name": "Panth",  
                "certifications": [  
                    {  
                        "title": "MCT"  
                    },  
                    {  
                        "title": "PMP"  
                    }  
                ]  
            }  
        ]  
    }  
}

Variables

So far we have written queries where we were passing hard coded values for the employeeid, here we can create a variable which can accept the value dynamically and return the response accordingly.

With the query name we need to mention variable; i.e., $employeeId and make it mandatory using the ! symbol. Replace hard coded employee id value with the variable; i.e., $employeeId. Before executing the query we need to pass employeeId value as Query Variables.

image.png

Query

query E1($EmployeeId : ID!)  
{  
  employee(id:$EmployeeId){name, certifications {title}}  
}

Query Variables

{  
  "EmployeeId": 2  
}

Query Response

{  
  "data": {  
    "employee": {  
      "name": "Panth",  
      "certifications": [  
        {  
          "title": "MCT"  
        },  
        {  
          "title": "PMP"  
        }  
      ]  
    }  
  }  
}

Syntax to call Named Queries from Postman

URLlocalhost:44332/graphql
MethodPOST
HeaderApplication/json

Request Body

{  
"query":"query all  
                {  
                  employees {name certifications {title}}  
                }  

         query E1($EmployeeId:ID!)  
                {  
                  employee(id:$EmployeeId){name, certifications {title}}  
                }",  
"OperationName":"E1",  
"variables":{"EmployeeId":2}  
}

Response

{  
    "data": {  
        "employee": {  
            "name": "Panth",  
            "certifications": [  
                {  
                    "title": "MCT"  
                },  
                {  
                    "title": "PMP"  
                }  
            ]  
        }  
    }  
}

Directive

Consider a scenario where your expectation is to get a response based on your query parameter, for example if value for Boolean parameter is passed as true then return a long description, or else don’t consider a long description in response. So declare a variable which expects true or false, which means a long description needs to be returned or not. And along with a long description in the query we can use inbuilt directive; i.e., @include(if: {condition}).

image.png

Query

   query all($ShowLongDescription : Boolean!)  
    {  
      employees  
      {  
        id  
        name  
        email  
        mobile  
        address  
        shortDescription  
        longDescription @include(if: $ShowLongDescription)  
    }  
    }

Query Variables

{  
  "ShowLongDescription":  false  
}

Query Response

{  
  "data": {  
    "employees": [  
      {  
        "id": 1,  
        "name": "Akshay",  
        "email": "akshayblevel@gmail.com",  
        "mobile": "9999999999",  
        "address": "Hyderabad",  
        "shortDescription": "Short Description"  
      },  
      {  
        "id": 2,  
        "name": "Panth",  
        "email": "panth@gmail.com",  
        "mobile": "8888888888",  
        "address": "Vadodara",  
        "shortDescription": "SD"  
      }  
    ]  
  }  
}

Optional Parameter

In the continuation of the above directive implementation, we can declare parameter as optional. For example, if someone doesn’t pass the expected value, in that case also it should work. So we have passed false as default parameter value. If you don’t pass value for showLongDescription it won’t return longDescription by default. If you want to get longDescription in your response, you need to pass parameter value as true.

image.png

Query

query all($ShowLongDescription : Boolean=false)  
{  
  employees  
  {  
    id  
    name  
    email  
    mobile  
    address  
    shortDescription  
    longDescription @include(if: $ShowLongDescription)  
}  
}

Query Response

{  
  "data": {  
    "employees": [  
      {  
        "id": 1,  
        "name": "Akshay",  
        "email": "akshayblevel@gmail.com",  
        "mobile": "9999999999",  
        "address": "Hyderabad",  
        "shortDescription": "Short Description",  
        "longDescription": "Long Description"  
      },  
      {  
        "id": 2,  
        "name": "Panth",  
        "email": "panth@gmail.com",  
        "mobile": "8888888888",  
        "address": "Vadodara",  
        "shortDescription": "SD",  
        "longDescription": "LD"  
      }  
    ]  
  }  
}

image.png

Query

query all($ShowLongDescription : Boolean=false)  
{  
  employees  
  {  
    id  
    name  
    email  
    mobile  
    address  
    shortDescription  
    longDescription @include(if: $ShowLongDescription)  
}  
}

Query Variables

{  
  "ShowLongDescription":  true  
}

Query Response

{  
  "data": {  
    "employees": [  
      {  
        "id": 1,  
        "name": "Akshay",  
        "email": "akshayblevel@gmail.com",  
        "mobile": "9999999999",  
        "address": "Hyderabad",  
        "shortDescription": "Short Description",  
        "longDescription": "Long Description"  
      },  
      {  
        "id": 2,  
        "name": "Panth",  
        "email": "panth@gmail.com",  
        "mobile": "8888888888",  
        "address": "Vadodara",  
        "shortDescription": "SD",  
        "longDescription": "LD"  
      }  
    ]  
  }  
}

I hope this will help you guys during your GraphQL implementation.