Graph Query Language (GraphQL) is a language and specification for interacting with GraphQL APIs, an HTTP-based client-server architecture for communication across the web.

Facebook released GraphQL as an alternative to the REST architectural standard. GraphQL addresses most of the issues with REST in a stateless and cacheable manner. It provides a simple and intuitive syntax that describes the expected output(s) or input(s), and the API relays the data matching the request.

Since GraphQL is a specification, you can build and consume GraphQL APIs in any server-side programming language, including Go.

Getting Started With GraphQL APIs in Go

GraphQL is based on HTTP architecture, and Go provides HTTP functionality in its built-in http package.

You can use the http package to consume RESTful APIs in Go, among other features. For GraphQL, you can make queries and mutations to GraphQL APIs servers with the http package and other built-in packages.

overview section of the Go  HTTP package

GraphQL client packages like Machinebox’s or shurCooL’s make the process of interacting with GraphQL APIs even easier.

You can use the http package without any dependencies to interact with a GraphQL API. Import these packages in your Go file to begin:

        import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "time"
)

You’ll use the bytes package to create a new buffer for the request and the json package to marshal a map to the JSON request body. You can use ioutil to read the response body, and the time package to set a time limit for the request.

Querying GraphQL APIs With Go

There are many free public GraphQL APIs you can query and integrate into your applications. For this article, you’ll query Apollo GraphQL’s Countries API to query data on countries worldwide.

All GraphQL operations are typically POST requests since they must have a payload (request body). Most GraphQL APIs accept JSON request body as the content type, and Go provides functionality for using maps and structs to work with JSON.

You’ll need to study the structure of the GraphQL schema to query the API. The query will be the same as a regular GraphQL query except that the operation (query or mutation) is the key, and the data is the map's value.

Here’s how you can declare a JSON map instance that you’ll marshal into JSON for the request.

        jsonMapInstance := map[string]string {
    "query": `
        {
            countries {
                name,
                phone,
                currency,
                code,
                emoji
            }
        }
    `,
}

The jsonMapInstance variable is the map instance for the request’s body. The value is a string of the query data you’re expecting from the API. In this case, the query data you’ll expect from the API’s countries schema are the name, phone, currency, code, and emoji fields.

You can use the Marshal method of the json package to encode the map instance to JSON. The Marshal method returns the encoded JSON and an error for cases with an encoding problem.

        jsonResult, err := json.Marshal(jsonMapInstance)
 
if err != nil {
    fmt.Printf("There was an error marshaling the JSON instance %v", err)
}

Once you’ve encoded the map to JSON, you can send the POST request to the API. You can create a new request instance with the NewRequest method, which takes in the request type, URL, and JSON buffer.

The NewRequest method returns a request instance. You'll have to set the content type depending on the API's specifications. You can set the content type for HTTP requests with the Set method of the Header method of your request instance.

        newRequest, err := http.NewRequest("POST", "https://countries.trevorblades.com/graphql", bytes.NewBuffer(jsonResult))
newRequest.Header.Set("Content-Type", "application/json")

You can create a simple HTTP client for your request with the Client method of the HTTP package. The Client method also allows you to set a time limit for your request with the time package.

        
client := &http.Client{Timeout: time.Second * 5}
response, err := client.Do(newRequest)
 
if err != nil {
    fmt.Printf("There was an error executing the request%v", err)
}

After you’ve declared the HTTP client, execute your API request with the Do method. The Do method accepts the request instance and returns the response and an error.

You can read the response of the API request with the ioutil package’s ReadAll method. It takes in an output stream and returns a byte slice of the data with an error that you can handle.

        responseData, err := ioutil.ReadAll(response.Body)
 
if err != nil {
    fmt.Printf("Data Read Error%v", err)
}

With the built-in string function, you can convert the byte slice response to the string type.

        fmt.Println(string(responseData))

Here’s a response showing the result of the API request:

The output from a GraphQL API query shows a list of countries and their requested fields.

Consuming RESTful APIs Is Like Consuming GraphQL APIs

Since both REST and GraphQL APIs use the HTTP protocol, consuming each is a very similar process, and you can use the http package for both cases.

You'll need to create clients, request instances, and read the data with the same packages.