Code Monkey home page Code Monkey logo

faunadb-go's Introduction

The Official Golang driver for v4 API of Fauna

Go Report Card GoDoc License

A Golang driver for FaunaDB.

Note: This driver supports an older version of the Fauna API. The latest version of the official Fauna Golang Driver is located here (we encourage all new development to use this new version where possible).

Supported Go Versions

Currently, the driver is tested on:

  • 1.13
  • 1.14
  • 1.15
  • 1.16

Using the Driver

Installing

To get the latest version run:

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

Please note that our driver undergoes breaking changes from time to time, so depending on our main branch is not recommended. It is recommended to use one of the following methods instead:

Importing

For better usage, we recommend that you import this driver with an alias import.

Using dep or go get

To import a specific version when using go get, use:

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

Basic Usage

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-secret-here")

	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)
}

Streaming feature usage

package main

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

func main() {
	secret := ""
	dbClient = f.NewFaunaClient(secret)
	var ref f.RefV
	value, err := dbClient.Query(f.Get(&ref))
	if err != nil {
		panic(err)
	}
	err = value.At(f.ObjKey("ref")).Get(&docRef)
	var subscription f.StreamSubscription
	subscription = dbClient.Stream(docRef)
	err = subscription.Start()
	if err != nil {
		panic("Panic")
	}
	for a := range subscription.StreamEvents() {
		switch a.Type() {
	
		case f.StartEventT:
			// do smth on start event
	
		case f.HistoryRewriteEventT:
			// do smth on historyRewrite event	
			
		case f.VersionEventT:
			// do smth on version event
			
		case f.ErrorEventT:
			// do smth on error event
			subscription.Close() // if you want to close streaming on errors
		}
	}
}

Omitempty usage

package main

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

func main() {
	secret := ""
	dbClient = f.NewFaunaClient(secret)
	var ref f.RefV
	value, err := dbClient.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 := dbClient.Query(
		f.Create(f.Collection("categories"), f.Obj{"data": OmitStruct{Name: "John", Age: 0}}))
	if err != nil {
		panic(err)
	}
}

Result (empty/zero fields will be ignored):

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

Http2 support

Driver uses http2 by default. To use http 1.x provide custom http client to FaunaClient

package main

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

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

For more information about Fauna Query Language (FQL), consult our query language [reference documentation](https://docs.fauna.com/fauna/v4/api/fql/).

Specific reference documentation for the driver is hosted at GoDoc.

Most users found tests for the driver as a very useful form of documentation Check it out here.

Contributing

GitHub pull requests are very welcome.

Driver Development

Run go get -t ./... in order to install project's dependencies.

Run tests against FaunaDB Cloud by passing your root database key to the test suite, as follows: FAUNA_ROOT_KEY="your-cloud-secret" go test ./....

If you have access to another running FaunaDB database, use the FAUNA_ENDPOINT environment variable to specify its URI.

Alternatively, tests can be run via a Docker container with FAUNA_ROOT_KEY="your-cloud-secret" make docker-test (an alternate Debian-based Go image can be provided via RUNTIME_IMAGE).

Tip: Setting the FAUNA_QUERY_TIMEOUT_MS environment variable will set a timeout in milliseconds for all queries.

LICENSE

Copyright 2020 Fauna, Inc.

Licensed under the Mozilla Public License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at

http://mozilla.org/MPL/2.0/

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

faunadb-go's People

Contributors

adambollen avatar alexandre-normand avatar alvarofauna avatar ashfire908 avatar bitbckt avatar clbray avatar cleve-fauna avatar cynicaljoy avatar dijkstracula avatar eaceaser avatar erickpintor avatar faunaee avatar hasante avatar jamesongithub avatar jfmiii avatar macnealefauna avatar marrony avatar parkhomenko avatar sprsquish avatar tysont avatar vadimlf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

faunadb-go's Issues

Fauna-go should ignore zero values when serializing/saving

Issue

Currently fauna-go sets values in the document even though they have a zero value.

Example:

running the following query will result in the following document:

type MyObject struct {
	MyString string
	MyInt int
}

myObj := MyObject{
	MyString: "",
	MyInt:    0,
}

res, err := s.fdb.Query(f.Create(f.Collection("my_collection"), f.Obj{"data": myObj}))
if err != nil {
	return nil, err
}

document:

{
  "ref": Ref(Collection("my_collection"), "286888125244899841"),
  "ts": 1609856686740000,
  "data": {
    "MyString": "",
    "MyInt": 0
  }
}

Suggested Solution

Fauna-db should implement functionality to discard zero valued fields. I.e. string values of "", int values of 0, float values of 0 should be discared.

I think this should be implemented via field struct tags, either via a opt-in to use serialize the zero values, or via a opt out. This is how serialization/deserialization of zero values in handling in other db drivers and in JSON.

For example the JSON field tags have the option to specify omitempty, which discards zero valued fields from serialization.

type MyObject struct {
	MyString string `json:",omitempty"`
	MyInt int `json:",omitempty"`
}

Conversely pg-go defaults to discarded zero values, but allows you to specify use_zero

type MyObject struct {
	MyString string `pg:",use_zero"`
	MyInt int `pg:",use_zero"`
}

I would propose that this is implemented using the omitempty option in the struct field tags. E.g:

type MyObject struct {
	MyString string `fauna:",omitempty"`
	MyInt int `fauna:",omitempty"`
}

Fetch array of items

How to fetch an array of items and unmarshal them to struct?

I tried using a Lambda, but I couldn't unmarshal the result to an array of my structs.

I ended up with this, but I guess this is doing too many requests to the DB, yes?

func (db DB) Users() ([]User, error) {
	res, err := db.client.Query(f.Paginate(f.Match(f.Index("all_users")), f.Size(99999)))
	if err != nil {
		return nil, err
	}

	var refs []f.RefV
	res.At(f.ObjKey("data")).Get(&refs)

	var users []User
	for _, ref := range refs {
		res, err := db.client.Query(f.Get(ref))
		if err != nil {
			return nil, err
		}
		var user User
		res.At(f.ObjKey("data")).Get(&user)
		users = append(users, user)
	}

	return users, nil
}

Errors lose nested error descriptions

Howdy!

I'm using this lib in conjunction w/ Fauna functions to make a GraphQL server. I know Fauna has a product for that - this is more of a learning project than anything else.

Anyway, I've created a create_user function that takes a lot of inspiration from the website's authentication tutorial:

// create_user
Query(
  Lambda(
    ["email", "handle", "password"],
    If(
      Or(
        Exists(Match(Index("user_ref_by_username"), LowerCase(Var("handle")))),
        Exists(Match(Index("users_by_email"), LowerCase(Var("email"))))
      ),
      Abort("the handle or username already exists"),
      Create(Collection("users"), {
        credentials: { password: Var("password") },
        data: {
          id: NewId(),
          email: LowerCase(Var("email")),
          displayName: Var("handle"),
          username: LowerCase(Var("handle"))
        }
      })
    )
  )
)

It creates a user only if the handle and email address is not unique. Otherwise, it Aborts with a message describing the problem. Calling this from the shell is helpful - I get exactly what I expect:

> Call("create_user", ["[email protected]", "Alker", "1234"])
Error: call error
{
  errors: [
    {
      position: [],
      code: 'call error',
      description: 'Calling the function resulted in an error.',
      cause: [
        {
          position: [
            'expr',
            'then'
          ],
          code: 'transaction aborted',
          description: 'the handle or username already exists'
        }
      ]
    }
  ]
}

However, the err from the call via this lib's client.Query(...) method only provides a synthesis of the top-level message:

Response error 400. Errors: [](call error): Calling the function resulted in an error."

This makes it hard to handle the error unambiguously. Does this library support either:

  1. Getting the full response w/ the raw error and its nested errors (or parsed into go struct)?
  2. Getting the error separately but in a form that exposes nested error fields?

If neither, does this make sense to add to the library? If so, where would be a good place to start? I don't mind contributing, but I started learning Go (and FaunaDB) a couple of weeks ago so I'm apprehensive about it at the moment.

go get not getting latest version - v2.9.0

I am trying to get faunadb-go with go get ./... but it always get this:

github.com/fauna/faunadb-go v2.0.0+incompatible // indirect
gopkg.in/fauna/faunadb-go.v2 v2.0.0

Tutorial example broken

This example from the tutorial isn't valid Go syntax:

func main() {
        
        res, err := client.Query(f.Concat(["Hello", "World"], " "))
        if err != nil {
                panic(err)
        }

        fmt.Println(res)
}

I changed it to this and it worked:

	res, err := client.Query(f.Concat([]string{"Hello", "World"}))
	if err != nil {
		panic(err)
	}

	fmt.Println(res)

Decode map to struct value

This is my code:

client := f.NewFaunaClient(os.Getenv("FAUNADB_SERVER_SECRET"))

	res, err := client.Query(f.Get(f.Ref("classes/Card")))
	if err != nil {
		panic(err)
	}

var cards []*m.Card

	if err := res.At(f.ObjKey("data")).Get(cards); err != nil {
		log.Println(err)
		return &events.APIGatewayProxyResponse{
			StatusCode: http.StatusMethodNotAllowed,
			Body:       "Error fetch data",
		}, nil
	}

This is the error message:

Error while decoding fauna value at: <root>. Can not decode map into a value of type "[]*card.Card"

"v2+" module name

(Problem) Description

for the v2+ version, the go modules need that the module path to sync with the major version.

https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher

Steps to reproduce

module github.com/yourusername/project

go 1.12

require (
	github.com/fauna/faunadb-go v2.12.0
)

Run go mod tidy

require github.com/fauna/faunadb-go: version "v2.12.0" invalid: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

Expected behaviour

module github.com/yourusername/project

go 1.13

require (
	github.com/fauna/faunadb-go v2.12.0
)

Actual behaviour

To be able to use the faunadb client, we are forced to use hash (pseudo-version) instead a real version

module github.com/yourusername/project

go 1.13

require (
	github.com/fauna/faunadb-go v1.0.1-0.20200506155252-ce35719ad41e
)

Suggested fix

Change the module name and update the package inside this repo.

module github.com/fauna/faunadb-go/v2

go 1.11

require (
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/stretchr/testify v1.2.2
)
package faunadb_test

import (
	"testing"
	"time"

	f "github.com/fauna/faunadb-go/faunadb/v2"
	"github.com/stretchr/testify/suite"
)

Calling methods results undefined ( .\main.go:36:28: undefined: faunadb.CreateCollection )

auth::go run main.go

command-line-arguments

.\main.go:36:28: undefined: faunadb.CreateCollection
.\main.go:45:15: undefined: faunadb.Collection
.\main.go:58:15: undefined: faunadb.Collection
.\main.go:70:4: undefined: faunadb.Collection
.\main.go:87:6: undefined: faunadb.Collection
.\main.go:97:45: undefined: faunadb.RefCollection
.\main.go:97:61: undefined: faunadb.Collection

When I isolate the file, it successfully works without giving me any errors, but when I add it to a project, it results in an error. This is just a small section of the problem. I found mostt others when I was using it resulted in some weird errors.

I have tried my best, but I just can't seem to solve it, please help me.

Unmapping

I apologize, but I can't figure this out. I did a map over an index to search for specific items. However, I cannot figure out how to get the data out of the faunadb.Value mapping. I have a struct called Cookie and I want to get all of the results from the index and map them into a slice of structs.

type Cookie struct {
        ID          string   `json:"id"`
        Name        string   `json:"name"`
        Cost        float64  `json:"cost"`
        Unit        string   `json:"unit"`
        Ingredients []string `json:"ingredients"`
}

type Cookies []Cookie
        resp, err := client.Query(
                f.Map(
                        f.Paginate(
                                f.MatchTerm(f.Index("ByIngredients"), ingredient)),
                        f.Lambda("cookie", f.Get(f.Var("cookie"))),
                ),
        )

Here's the data I get back:

map[data:[map[data:map[ingredients:[chocolate chips] name:Chocolate Chip price:10 unit:dozen] ref:{265047217107108372 0xc000584240 <nil>} ts:1589028306980000] map[data:map[ingredients:[chocolate love] name:Brownie price:10 unit:dozen] ref:{265245928522252820 0xc000584640 <nil>} ts:1589217079570000]]]

I just can't figure out how to unmap this with resp.Get()

relations in structs

hi, i think relations in golang are of type:

faunadb.refFn

but since type refFn is not exported i can't use it in a struct

type Profile2 struct {
  Text        string   `fauna:"text"`
  Relation  f.refFn  `fauna:"relation"`
}

i am doing it with f.Ref()

there is another way?

Error when setting time to live on Create

In the documentation for Create I can see that it supports a TTL parameter, which takes a Fauna Timestamp object: https://docs.fauna.com/fauna/current/api/fql/functions/create

In the documentation for Timestamps, it says the code to use for the Go library is faunadb.Time but when I do so, I get an error saying that faunadb.Time is not a type.

I can't find Time in the code, but I have found some similar things, like TimeV. Would that be the type to use for timestamps? I see that it's basically just a wrapper around the Go stdlib time.Time object.

go get command fails with "no buildable Go source files"

I ran into an error running go get:

$ go get github.com/fauna/faunadb-go
package github.com/fauna/faunadb-go: no buildable Go source files in /$GOPATH/src/github.com/fauna/faunadb-go

This works:

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

To have go get github.com/fauna/faunadb-go work as stated, you'd need to move everything from /fauna/* up a directory into the root.

Show where parsing error occurred

I am trying to convert the following code into golang, we have an existing firebase app but we are attempting to convert it into faunadb. I have more complex authentication requirements and therefore cannot use faunadb's built-in system. My solution is to write a go Lamba function that can handle login/sign up functionality.

Create(
  Tokens(), {
    instance: Select("ref", Get(Match(Index('users_by_email'), "[email protected]")))
  }
)
func loginUser(email string) {
	expr := fauna.Create(fauna.Tokens(), fauna.Select("ref",
		fauna.Get(
			fauna.MatchTerm(fauna.Index("users_by_email"), email),
		),
	))
	value, err := client.Query(expr)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(value)
	}
}

I'm very new to faunadb, I get this error when running the above code snippet.
Response error 400. Errors: [params](invalid argument): Object expected, Ref provided.

This isn't the best to help debug, what would be more helpful is to return a FQL string with the error section highlighted in red.
Would this be a feature you can implement?

P.S.

Would appreciate any help with the above issue

Documentation error on f.RefCollection

In the godocs, collections are referred by f.RefCollection("someRef") Method. However, in practice, f.Ref("collections/someRef") is the right way to get the reference of a specific collection. Is it miss-documented?

FEATURE REQUEST

Queries like Cloud Firestore given that it has Documents. ie db.collection("users").doc("id").get()
I'm a noob at this though

Vercel uses 2.0.0+incompatible

Vercel supports Go, and FaunaDB + Vercel is a promising setup. However, Vercel uses a go.mod file to setup the runtime environment. As per other issues, such as #90, the go mod dependency setup produces some version issues.

The main issue is that Vercel grabs version 2.0.0+incompatible from 2018. I can't the docs for this version. Could you provide link to the docs. Otherwise what is the course of action so that go mod grabs the current version?

Can't use faunadb-go

Hello,
I want to evaluate FaunaDB but it's not possible due to #77

Error:

go get github.com/fauna/[email protected]: github.com/fauna/[email protected]: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

Therefore the CI wasn't fixed for more than 20 days. Is this module still maintained?

Related: golang/go#35732

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.