Go driver

Go logo

This section describes Fauna’s open source Go driver, which provides the resources required to interact with Fauna.

Current stable version

4.2.0

Repository

Supported Go versions

Currently, the driver is tested on the following Go versions:

  • 1.13

  • 1.14

  • 1.15

  • 1.16

Install

To get the latest version run:

go get github.com/fauna/faunadb-go/v4/faunadb

Please note that the driver undergoes breaking changes from time to time. It is recommended to use one of the following methods instead:

Usage

Here is an example demonstrating how to use the Go driver to execute a simple query on Fauna:

Use the correct endpoint value for your database’s Region Group.
package main

import (
    "fmt"
    f "github.com/fauna/faunadb-go/v4/faunadb"
)

type User struct {
    Name string `fauna:"name"`
}

func main() {
    client := f.NewFaunaClient(
        "YOUR_FAUNA_SECRET",
        f.Endpoint("http://localhost:8443/")
        // NOTE: use the correct endpoint for your database's Region Group.
    )

    res, err := client.Query(f.Get(f.Ref(f.Collection("user"), "42")))
    if err != nil {
        panic(err)
    }

    var user User

    if err := res.At(f.ObjKey("data")).Get(&user); err != nil {
        panic(err)
    }

    fmt.Println(user)
}

See Connections for more details on creating client connections. See Region Groups for more details on domain names for Region Groups.

Query timeout

Your code can configure the client to handle timeouts in two different ways:

  1. by adding a call to QueryTimeoutMS to the options block when instantiating the client, or

  2. by adding a call to TimeoutMS as the second parameter to the .Query method.

When you provide a query timeout, the server waits for the specified period before timing out, if it has yet to complete the current query. Once the period has elapsed, the query fails and the server responds with an error.

Both timeouts are expressed in milliseconds.

For example:

// Specify a query timeout during client instantiation
client := f.NewFaunaClient(
	"secret",
	f.QueryTimeoutMS(1))
// Specify a query timeout per query
result, err := client.Query(
	 f.Paginate(f.Collections()),
	 f.TimeoutMS(1))

The value used in the TimeoutMS call passed to .Query() takes precedence over any value used in the QueryTimeoutMS call during client instantiation.

omitempty usage

When marshalling JSON data into Fauna queries, or out of Fauna responses, the omitempty tag can help deal with variability in JSON documents:

package main

import f "github.com/fauna/faunadb-go/v4/faunadb"

func main() {
	secret := "YOUR_FAUNA_SECRET"
	client = f.NewFaunaClient(secret)
	var ref f.RefV
	value, err := client.Query(f.Get(&ref))
	if err != nil {
		panic(err)
	}

	type OmitStruct struct {
		Name           string      `fauna:"name,omitempty"`
		Age            int         `fauna:"age,omitempty"`
		Payment        float64     `fauna:"payment,omitempty"`
		AgePointer     *int        `fauna:"agePointer,omitempty"`
		PaymentPointer *float64    `fauna:"paymentPointer,omitempty"`
	}

	_, err := client.Query(
		f.Create(f.Collection("categories"), f.Obj{"data": OmitStruct{Name: "John", Age: 0}}))
	if err != nil {
		panic(err)
	}
}

When you run this example (be sure to replace YOUR_FAUNA_SECRET with your actual secret), the result should exclude empty/zero fields:

{
  "ref": Ref(Collection("categories"), "295143889346494983"),
  "ts": 1617729997710000,
  "data": {
    "name": "John"
  }
}

HTTP/2 support

The Go driver uses HTTP/2 by default. To use HTTP/1.x, provide a custom HTTP client to FaunaClient:

package main

import (
  f "github.com/fauna/faunadb-go/v4/faunadb"
  "net/http"
)

func main() {
	secret := ""
	customHttpClient := http.Client{}
	client = f.NewFaunaClient(secret, f.HTTP(&customHttpClient))
}

Event streaming

This section demonstrates how to subscribe to change events. To learn more, see Event streaming.

There are two kinds of event streaming:

The code required to subscribe to each type is very similar. The primary difference is the type of Reference involved in the subscription, and the kinds of events that are included in the stream.

There is a cost in compute operations to hold a stream open, or to repeatedly start a stream that fails.

See Billing for details.

Document streaming

The following example subscribes to change events for a specific document:

	client := f.NewFaunaClient(secret, f.Endpoint(endpoint))

	// Define a reference to the document that we want to stream
	// Note that the Scores collection must already exist
	var ref = f.Ref(f.Collection("Scores"), "1")

	// Setup the stream subscriber
	var subscription f.StreamSubscription
	subscription = client.Stream(ref)
	err := subscription.Start()
	if err != nil {
		fmt.Println(err)
		panic("Panic")
	}

	// Handle stream events
	for event := range subscription.StreamEvents() {
		fmt.Println(event)
		switch event.Type() {
			case f.StartEventT:
				// Do something with the start event

			case f.HistoryRewriteEventT:
				// Do something with history rewrite events

			case f.VersionEventT:
				// Do something with version events

			case f.ErrorEventT:
				// Handle stream errors
				// In this case, we close the stream
				subscription.Close()
		}
	}

Before you run the example:

  1. Set the FAUNADB_SECRET environment variable, and optionally the FAUNADB_ENDPOINT environment variable (if you are using Region Groups or Fauna Dev).

  2. The collection Scores must exist.

Once the example is running, you can use the Fauna Dashboard, or another client application, to create or update the target document and watch the events arrive as the changes are made.

For example, if the document does not yet exist, you could run this query in the Fauna Dashboard Shell:

Create(Ref(Collection("Scores"), "1"), { data: { scores: [1, 2, 3] }})

Once the document exists, you could run this query:

Update(Ref(Collection("Scores"), "1"), { data: { scores: [5, 2, 3] }})

The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.

Set streaming

The following example subscribes to change events for a set:

	client := f.NewFaunaClient(secret, f.Endpoint(endpoint))

	// Define the reference to the target set
	var ref = f.Documents(f.Collection("Scores"))

	// Define the stream fields to include
	var streamOptions = f.Fields("action", "document", "index")

	// Setup the stream subscriber
	var subscription f.StreamSubscription
	subscription = client.Stream(ref, streamOptions)
	err := subscription.Start()
	if err != nil {
		fmt.Println(err)
		panic("Panic")
	}

	// Handle stream events
	for event := range subscription.StreamEvents() {
		fmt.Println(event)
		switch event.Type() {
			case f.StartEventT:
				// Do something with the start event

			case f.SetEventT:
				// Do something with set events

			case f.ErrorEventT:
				// Handle stream errors
				// In this case, we close the stream
				subscription.Close()
		}
	}

Before you run the example:

  1. Set the FAUNADB_SECRET environment variable, and optionally the FAUNADB_ENDPOINT environment variable (if you are using Region Groups or Fauna Dev).

  2. The collection Scores must exist.

Once the example is running, you can use the Fauna Dashboard, or another client application, to add or delete documents in the "Scores" collection and watch the events arrive as the changes are made. For example, you could run this query in the Fauna Dashboard's Shell:

Create(Collection("Scores"), { data: { scores: [5, 6, 7] }})

The streaming example waits indefinitely for events. Use Ctrl+C to terminate the program.

Next steps

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!