GraphQL queries with examples using Tyk

Note: All example queries from this post can be tried out in countries.trevorblades.com

Queries are the basic way to interact with any GraphQL API. With a large and vibrant GQL community, some great tooling has been introduced that make that interaction easy even for users who have not used GraphQL before. If you’re just getting started though, it can get overwhelming anyway, so keep reading on – this post might help to get you started seamlessly.

Understanding the basics

A GraphQL query is a string that defines the data structure that the client is requesting. It allows the client to request only the information it needs, and the server responds with exactly that data. The query is sent to a GraphQL server over HTTP or another transport protocol. This is basically the client telling the server what exactly it wants to get back.

A lot of GraphQL services will offer GraphiQL Playground  to make interaction with the backend easier and more user-friendly. The Playground gives user a few options:

  • Explore the GQL API documentation – browse through the graph schema, see how the data model looks like, what types and fields can be queried, what sort of parameters and variables can be used. This is where you get to know the GQL server a bit to understand how you can query it.
  • History of operations executed – it’s a list of previous operations (queries, mutations and subscriptions) that you executed through the Playground. Very useful in case you want to go back to something and modify it, without having to write a large query again from scratch.
  • Auto-complete and suggest – pressing Ctrl+Space will pull up a list of types and fields you can use at a certain level of your query and starting to type will refine that list.

Simple GQL query

Let’s start small and write a very simple GQL query, so that we can get to know the syntax a bit better.

query withoutVariable {
  continents {
    code
    name
    countries {
      name
      capital
    }
  }
}

Let’s now pick this apart, to understand what’s what.

  • query  is the keyword indicating that this is a query operation.
  • withoutVariable is the user-defined query name. This is a good way of keeping track of the queries you execute in order to get back to them later on using the Playground history feature.
  • continents  is the name of the query operation. It already suggests that we intend to find a list of continents, so the response will most likely be an array of objects. If we were to check the documentation, we’d see that this assumption is correct, but even the query name suggests it.
  • code , name and countries  are the fields describing each continent that we’re looking to get. countries is a bit different to code and name because it’s a field that returns an array of information, so name and capital  that we’re requesting within countries are referring to each country, not to continent.

So what we should get in this case is a response that contains a list of continents and for each continent we should be seeing its name, code and a list of countries in it. For each country then we’ll see its name and capital. The response might look something like this:

{
    "data": {
      "continents": [
        {
          "code": "AF",
          "name": "Africa",
          "countries": [
            {
              "name": "Angola",
              "capital": "Luanda"
            },
            {
              "name": "Burkina Faso",
              "capital": "Ouagadougou"
            },
            ...
            {
              "name": "Zimbabwe",
              "capital": "Harare"
            }
          ]
        },
        {
          "code": "AN",
          "name": "Antarctica",
          "countries": [
            {
              "name": "Antarctica",
              "capital": null
            },
            ...
            {
              "name": "French Southern Territories",
              "capital": "Port-aux-Français"
            }
          ]
        }
        ...
      ]
    }
  }

Simple GQL query with variable

It might happen that a GQL query requires client to provide a variable as part of it. Referring to the previous example – if we only wanted to get a single country information, we could see a query like this:

query withVariable {
  country(code: "MZ") {
    name
    capital
    currency
    languages {
      code
      name
      native
    }
  }
}

We see some familiar sections in here already: query , user-defined name withVariables  and then name of the query operation country and some fields we’re requesting. But this time we’re providing a code which means we’re only wanting to see information about a single country – MZ .The response will no longer be an array, but a single object. It will look like this:

{
  "data": {
    "country": {
      "name": "Mozambique",
      "capital": "Maputo",
      "currency": "MZN",
      "languages": [
        {
          "code": "pt",
          "name" "Portuguese",
          "native": "Português"
        }
      ]
    }
  }
}

Defining variables in GQL queries

Query variables in GQL queries can be provided to the server two different ways. One way, probably the easiest when you’re just starting out is the one showed above. If you were to look at the cURL request that gets generated, we’d see this:

curl --location 'https://countries.trevorblades.com/' \
--header 'Content-Type: application/json' \
--data '{"query":"query withVariable {\n  country(code: \"MZ\") {\n    name\n    capital\n    currency\n    languages {\n      code\n      name\n      native\n   }\n  }\n}"}'

The other would be to define the variable name in the query and provide its value separately. In GraphiQL Playground it would look like this:

The cURL will look like this:

curl --location 'https://countries.trevorblades.com/' \
--header 'Content-Type: application/json' \
--data '{"query":"query withVariable ($countryCode: ID!) {\n  country(code: $countryCode) {\n    name\n    capital\n    currency\n    languages {\n      code\n      name\n      native\n    }\n  }\n}","variables":{"countryCode":"MZ"}}'

The response will be exactly the same of course, but for queries with more variables, more complex ones, especially ones that you run often, it might make sense to send variable values like this.

GQL queries with fragments

In the context of queries, GQL allows user to define query fragments. Query fragments are a way to reuse parts of a query in multiple places. Fragments allow you to define a set of fields and then include those fields in your queries. This promotes code reuse and makes your queries more modular and maintainable.Let’s take a look at how a fragment could be defined and then used:

fragment CountryInfo on Country {
  code
  capital
  currency
}

query withFragments1{
  country(code: "PL") {
    ...CountryInfo
  }
}

query withFragments2{
  country(code: "US") {
    ...CountryInfo
  }
}

In this example:

  • The CountryInfo fragment is defined with the fields code, capital, and currency for the Country type.
  • The query uses the CountryInfo fragment for two separate user queries (withFragments1 and withFragments2).

By using fragments, you avoid duplicating the same fields in multiple places, making your queries more concise and easier to maintain. It’s important to note that fragments are not standalone queries; they must be included in a query using the spread operator (... ).

A query can include more than just one fragment, it all depends on how you define it. Here’s a more complex example:

fragment CountryInfo on Country {
  code
  capital
  currency
}

fragment ContinentInfo on Continent {
  code
  name
}

query withFragments1{
  country(code: "PL") {
    ...CountryInfo
    continent {
      ...ContinentInfo
    }
  }
}

query withFragments2{
  country(code: "US") {
    ...CountryInfo
    continent {
      ...ContinentInfo
    }
  }
}

Query aliases

GQL offers a way to rename the result of a field in the response. It allows you to request the same field with different arguments or request multiple fields of the same type while giving each field a unique name in the response.Let’s get back to that simple query from the beginning, which generated this response:

{
    "data": {
      "continents": [
        {
          "code": "AF",
          "name": "Africa",
          "countries": [
            {
              "name": "Angola",
              "capital": "Luanda"
            },
            {
              "name": "Burkina Faso",
              "capital": "Ouagadougou"
            },
            ...
            {
              "name": "Zimbabwe",
              "capital": "Harare"
            }
          ]
        },
        {
          "code": "AN",
          "name": "Antarctica",
          "countries": [
            {
              "name": "Antarctica",
              "capital": null
            },
            ...
            {
              "name": "French Southern Territories",
              "capital": "Port-aux-Français"
            }
          ]
        }
        ...
      ]
    }
  }

It might happen that for development reasons or cross-system compatibility we’d prefer the response to come as:

{
    "data": {
      "listOfContinents": [
        {
          "code": "AF",
          "name": "Africa",
          ....

So we want listOfContinents  rather than just continents . GQL allows you to do that by using query alias in your query.

query withoutVariable {
  listOfContinents: continents {
    code
    name
    countries {
      name
      capital
    }
  }
}

Field aliases

You can do exactly the same thing with every field in your query. Use aliases to effectively rename fields in the response. Aliases allow you to request the same field with different names in the query, and the server will return the corresponding data with those aliases in the response. Here’s an example of how you could change the field code into continentCode .

query withoutVariable {
  listOfContinents: continents {
    continentCode: code
    name
    countries {
      name
      capital
    }
  }
}

While you cannot directly change the names of fields in the schema itself (the schema defines the structure of the data), aliases in queries provide a way to achieve similar results in the response. Aliases are commonly used for improving the clarity of the response or avoiding naming conflicts when querying for similar data multiple times.

Summary

As you can see GQL queries are not that complicated to write, you just need a bit of practise. The syntax is quite intuitive and easy to understand. There’s a lot of flexibility when it comes to naming your queries and renaming the fields in the response, so that they fit your needs.
Tyk supports GraphQL natively and offers a wide range of functionalities that help you not only to interact with GQL APIs, but also to manage them in a secure way. We offer a built-in GQL Playground in Tyk Dashboard, but also a public GQL Playground your users can interact with securely. The built-in GQL Playground is providing detailed request logs that can help you debug your queries and spot any issues if they occur.You can read more in our docs and also on our blog.