Getting Started with Go and GraphCMS

As more people use "GraphCMS as a Database", we'll explore how to query GraphCMS inside of your Go program.

Jamie Barton
Jamie Barton
Working with GraphCMS and GO

Go is an open-source programming language that has seen significant adoption over the last few years and has become the backbone to many banks, businesses, and API platforms across the world.

As more people use "GraphCMS as a Database", just like we saw with working with Express.js, we can query GraphCMS just like we would any other database. Go has no opinion on where your data comes from, just as long as you structure your data access the right way.

We'll use Go modules, and since I don't plan to use this as a package I can share with others, I'll just name it with-golang.

go mod init using-golang

Then using Go modules I'll go get the graphql client package by Gopher Mat Ryer, and Machinebox.

go get github.com/machinebox/graphql

Now let's begin writing our Go program!

touch main.go

Inside there you'll want to declare the main package, import our GraphQL client module we just installed, and define a client variable.

ℹ️ If you're using Visual Studio Code, you can install the Go extension, which will automatically format (fmt), and do its best to manage your imports as and when you use them.

package main
import "github.com/machinebox/graphql"
var client *graphql.Client
func main() {
// ...
}

Let's now create a function for setupClient() and assign it to the client variable.

func setupClient() {
client = graphql.NewClient("https://api-eu-central-1.graphcms.com/v2/ck8sn5tnf01gc01z89dbc7s0o/master")
}

ℹ️ The endpoint above is open to all for querying, so no authentication is required.

Before we can use the client to make a NewRequest to GraphCMS, it's best we define a struct for our Product, and Response.

You don't need to do this, but Go would much prefer you to. 😉

The first struct for Product will contain our name, description, and price fields we have in our GraphCMS schema. We'll assign these to string, string, and int respectively.

While we're at it, we'll specify the json format of these too.

type Product struct {
Name string `json:"name"`
Description string `json:"description"`
Price int `json:"price"`
}

Next, let's define the ProductResponse, you could call this QueryResponse but this will define the shape of the response from GraphCMS. This must match our GraphQL query.

type ProductResponse struct {
Products []Product `json:"products"`
}

ℹ️ You might want to format and account for any errors here too.

Let's now create a function getAllProducts() where we will make our request to client.

Our query must match the struct of Product and ProductResponse above.

func getAllProducts() {
query := graphql.NewRequest(`
{
products {
name
description
price
}
}
`)
ctx := context.Background()
var responseData ProductResponse
if err := client.Run(ctx, query, &responseData); err != nil {
log.Fatal(err)
}
}

You could define your query outside of this and pass it into a new function, and instead of using context you could use the context of a http request if you ran this code as an HTTP handler.

But for now, let's add a bit more to this function to print our response as JSON.

jsonResponse, _ := json.MarshalIndent(responseData, "", "\t")
fmt.Printf("%+v\n", string(jsonResponse))

Then all that's left to do is update the main function to call both our functions.

func main() {
setupClient()
getAllProducts()
}

That's it! Give it a try via your terminal:

go run main.go

Here's the full main.go file, including the imports:

package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/machinebox/graphql"
)
type ProductResponse struct {
Products []Product `json:"products"`
}
type Product struct {
Name string `json:"name"`
Description string `json:"description"`
Price int `json:"price"`
}
var client *graphql.Client
func setupClient() {
client = graphql.NewClient("https://api-eu-central-1.graphcms.com/v2/ck8sn5tnf01gc01z89dbc7s0o/master")
}
func getAllProducts() {
query := graphql.NewRequest(`
{
products {
name
description
price
}
}
`)
ctx := context.Background()
var responseData ProductResponse
if err := client.Run(ctx, query, &responseData); err != nil {
log.Fatal(err)
}
jsonResponse, _ := json.MarshalIndent(responseData, "", "\t")
fmt.Printf("%+v\n", string(jsonResponse))
}
func main() {
setupClient()
getAllProducts()
}

I hope you found this useful, and to learn more about using Go with GraphCMS, I recommend you check the README on GitHub for github.com/machinebox/graphql.

Get the code for this article on GitHub.

It's Easy To Get Started

GraphCMS plans are flexibly suited to accommodate your growth. Get started for free, or request a demo to discuss larger projects with more complex needs