Isomorphic Go client for PostgREST.

Overview

Postgrest GO

golangci-lint CodeFactor

Golang client for PostgREST. The goal of this library is to make an "ORM-like" restful interface.

Documentation

Full documentation can be found here.

Quick start

Install

go get github.com/supabase/postgrest-go

Usage

package main

import (
	"fmt"

	"github.com/supabase/postgrest-go"
)

func main() {
	client := postgrest.NewClient("http://localhost:3000", "", nil)
	if client.ClientError != nil {
		panic(client.ClientError)
	}
	
	result := client.Rpc("add_them", "", map[string]int{"a": 12, "b": 3})
	if client.ClientError != nil {
		panic(client.ClientError)
	}
	
	fmt.Println(result)
}

License

This repo is liscenced under Apache License.

Sponsors

We are building the features of Firebase using enterprise-grade, open source products. We support existing communities wherever possible, and if the products don’t exist we build them and open source them ourselves. Thanks to these sponsors who are making the OSS ecosystem better for everyone.

New Sponsor

Watch this repo

Issues
  • `Execute()` is not sending request to the correct URL

    `Execute()` is not sending request to the correct URL

    Bug report

    Describe the bug

    So when I try to insert data with the following code snippet, I expect it to send a request to https://<supabase_url>/rest/v1/products but it seems like the Execute() function is not sending the request to the correct URL. image

    The result of trying to run this is that I get the response as below, after a google search it seems like this is what Kong would respond if it can't find a route

    image

    So I try to directly change the client.clientTransport.baseURL.Path to https://<supabase_url>/rest/v1/products, the request is sent to the correct place where I can see a postgrest response but the query is still not successfully created yet. I'm suspecting is that the way the querybuilder marshal json is making some errors here.

    image

    To Reproduce

    Steps to reproduce the behavior, please provide code snippets or a repository:

    1. Get the library
    2. Use a supabase url, anon key and proper auth token to create the client
    3. Try to insert data into a table
    4. See error

    Expected behavior

    The request should be sent to the correct url and querybuilder should properly marshal value into json

    Screenshots

    Shown above

    System information

    • OS: macOS Big Sur 11.4
    • Version of Go: 1.16

    Additional context

    I will try fixing it and if I do, I will create a PR.

    bug 
    opened by marcustut 8
  • Select from table fails

    Select from table fails

    Bug report

    Describe the bug

    Following the test example and the supabase-js example in the documentation I am not able to fetch data using the From().Select() chain and an error is returned in the response body instead of the err value itself.

    The json response looks like:

    {"message":"no Route matched with those values"}
    

    To Reproduce

            type User struct {
    		id string
    	}
            
            var (
    	        headers = map[string]string{"Authorization": fmt.Sprintf("Bearer %s", serverconf.Supabase.Key)}
    	        schema  = "public"
            )
    
            var serverconf := utils.NewServerConfig()
    
            supabaseClient := postgrest.NewClient(serverconf.Supabase.URL, schema, headers)
    		
            res, err := r.client.From("users").Select("*", "", false).Eq("email", email).Execute()
    
    	if err := json.Unmarshal(res, &result); err != nil {
    		panic(err)
    	}
    
    

    Expected behavior

    Expected to have a valid user response and no error. Also expected error to be returned in err variable but instead it's nil.

    bug 
    opened by txbrown 6
  • Provide examples for authentication etc.

    Provide examples for authentication etc.

    Hey! I love the idea behind this package, but have some troubles with getting started, as I am new to Supabase and PostgREST.

    I would love to see some more examples on the usage of this package (with supabase), namely authentication.

    • (How) should I use the client.TokenAuth method?
    • Can I encode the credentials into the HTTP URI somehow?

    For anything I tried, I get some not-so-descriptive error (like just EOF from net/url) which is very likely because I did something wrong.

    All the examples I can find are just for a local setup without auth. Maybe adding a few more tests would be ideal for this? I would love to contribute once I used this a bit more.

    I would greatly appreciate any help :)

    opened by Carnageous 5
  • New execute method for json objects

    New execute method for json objects

    What kind of change does this PR introduce?

    This PR implements a new executeTo method which automatically parses the response into a json object as described in #7

    What is the current behavior?

    #7

    What is the new behavior?

    An ExecuteTo method was added to the structs as described which directly parses the response body into an interface{}

    Additional context

    I tried to implement the changes described in the issue but was not sure regarding the requriements. I currently implemented the functions as requested with the return value of an (interface{}, error) for the ExecuteTo functions.

    I also thought about changing the function to ExecuteTo(target interface{}) error which enables the user to give a custom struct or map from outside. Then instead of creating a new object inside the executeTo function, this target value is used to parse the response body into. I would be open to implement this function as well - maybe under a different name like ExecuteInto

    As this is my first contribution, i hope i didn't miss something or did something wrong, if so please let me know so i can fix it!

    opened by aaronschweig 3
  • Reassign transformer methods to FilterBuilder

    Reassign transformer methods to FilterBuilder

    In lieu of a more ergonomic option within Go's type system (that feels reasonable) to resolve #8, I'm proposing removing TransformBuilder and simply reassigning its associated methods to FilterBuilder. As you'd expect, this lets you do:

    c.From("users").Select("*", "", false).Limit(10)
    

    Of course, it also somewhat unfortunately lets you do:

    c.From("users").Select("*", "", false).Limit(10).Eq("name", "sean")
    

    Which obviously looks weird.

    Since the transformer methods aren't usable in the current release, this is probably also a good time to discuss some of ergonomics around the transformer methods. Having four params with type similarities in Order, for example, feels a bit unnatural, so I'd propose having it instead accept a struct of options (or nil to get the defaults).

    type OrderOpts struct {
    	Ascending    bool
    	NullsFirst   bool
    	ForeignTable string
    }
    
    func (f *FilterBuilder) Order(column string, opts *OrderOpts) *FilterBuilder
    

    This also roughly mirrors the interface in postgres-js. I'm unsure whether it'd be useful to also update Limit and Range similarly, given they both also currently accept foreignTable.

    A full PR would need tests/docs -- this is just aimed at opening up discussion.

    opened by boatilus 2
  • Update ExecuteTo funcs to return count

    Update ExecuteTo funcs to return count

    Updates the ExecuteTo funcs to return (countType, error), mirroring the recent changes to Execute and ExecuteString, and adds a couple test cases.

    This also fixes a couple broken links in the README, peppers in a handful of doc comments, details how some of the tests are set up/how to run, and adds a script in the test directory that can be used to seed the current test DB. So there've been a number of files touched. If desired, I can split these into multiple PRs.

    I assumed this PR would be rolled into a v0.0.6 release and updated the version variable accordingly.

    opened by boatilus 2
  • Change authorization header

    Change authorization header

    After looking a bit at the supabase documentation, I saw that the authentication is not Basic but Bearer (which means in return that one should have to change this in the client.go file of postgrest.) I propose two solution:

    • whether to amend it on the static string of the TokenAuth (I just did it myself line 59 of client.go). then is will go to
    func (c *Client) TokenAuth(token string) *Client {
    	c.clientTransport.header.Set("Authorization", "Bearer "+token)
            ...
    }
    \\ instead of 
    func (c *Client) TokenAuth(token string) *Client {
    	c.clientTransport.header.Set("Authorization", "Basic "+token)
            ...
    }
    
    • or to amend it dynamically (I do not really now how PostgreSQL works, so if there are different type of authorization I could envisage the following)
    func (c *Client) TokenAuth(token string, auth_type string) *Client {
    	c.clientTransport.header.Set("Authorization", auth_type+" "+token)
            ...
    } 
    \\ instead of 
    func (c *Client) TokenAuth(token string) *Client {
    	c.clientTransport.header.Set("Authorization", "Basic "+token)
            ...
    }```
    opened by BenjaminArfa 2
  • Minor changes to headers in client.go

    Minor changes to headers in client.go

    As mentioned in https://github.com/supabase-community/postgrest-go/issues/20, I think that the two changes in this PR will solve bugs. I have no idea if others also experienced this, but for me both the missing header and the "wrong" header name made the package unusable for me.

    I am using go 1.17 btw.

    opened by Carnageous 2
  • X-Client-Info header

    X-Client-Info header

    we're rolling out a header similar to Stripe's App-Data in all of the client libs so issues can be debugged more easily between the client and the backend

    the javascript libs are done already: https://github.com/supabase/supabase-js/pull/238

    the format is: X-Client-Info: supabase-js/1.11.0

    for client libs that wrap others (like how supabase-js wraps gotrue-js) we allow the wrapper lib to overwrite the wrapped lib's header (given that we can infer the gotrue-js version based on which supabase-js was used to make the call)

    any help with rolling this out here would be incredible

    help wanted good first issue 
    opened by awalias 2
  • From() will always append the table name to the baseUrl Path

    From() will always append the table name to the baseUrl Path

    Bug report

    Describe the bug

    When using From(), the code will currently forcibly (+=) add the table name to the client transport baseUrl path. This makes it impossible to reuse a client instance (postgrest.NewClient(<url>L, <schema>, <headers>)) as the second time From() is used the schema becomes <schema>.<table><table>

    To Reproduce

    Steps to reproduce the behavior, please provide code snippets or a repository:

    var (
    	url = "https://<some-supabase-url>/rest/v1/"
    	headers  = map[string]string{"apikey": "<my-supabase-apikey>"}
    )
    
    client := postgrest.NewClient(url, "public", headers)
    
    // .. build some list
    for _, doc := range listofdocs {
        // Second time this is called, there will be an error because the schema is now wrong
    	resp, err := client.From("<mytable>").Insert(doc, "", "", "").Execute()
    	if err != nil {
    		// handle error
    	}
    }
    

    Expected behavior

    Expected behavior is that if calling multiple times (vs batch insert) that From() wont cause the insert to fail. The JS client (for example) does not exhibit this issue

    Screenshots

    N/A

    Additional context

    I am working on a solution to this that I will submit a PR for

    bug 
    opened by intabulas 2
  • In cases of non 20x responses, return an error from Execute()

    In cases of non 20x responses, return an error from Execute()

    What kind of change does this PR introduce?

    This PR allows Execute() to actually return an error if a non 20x response is received from supabase.

    What is the current behavior?

    Currently, if an error is received, Execute() return a nil error and the response from supabase. This then requires the user to determine if an error occurred by the contents of the response bytes

    ex:

    resp, err := client.From("sometable").Insert(document, false, "", "", "").Execute()
    // error will always be nil with current behavior, if (for example) sometable doesnt exist
    if err != nil {
      // nothing to handle
    }
    

    What is the new behavior?

    resp, err := client.From("sometable").Insert(document, false, "", "", "").Execute()
    // error will not be nil if any non 20x error is returned from supabase
    if err != nil {
      // print, or log, or return etc
      fmt.Printf("ERROR: %s\n", err)
    }
    

    Additional context

    I made two decisions that could be changed. The first was to include Hint and Details in the response struct, even though they are not used. The second was do do >= 300 vs 400 on the error check,

    opened by intabulas 2
  • ❓ Can't get it to work.

    ❓ Can't get it to work.

    Synopsis

    I can't get this package to function against supabase.co

    Details

    Whether I use the Anon key or the Service key, I can't select anything.

    • With head set to false, I get []
    • With head set to true, I get ""

    Reproduction

    func TestSelect(t *testing.T) {
    	db := postgrest.NewClient(
    		"https://<project-ref>.supabase.co/rest/v1/",
    		"public",
    		map[string]string{},
    	)
    	db.TokenAuth("...")
    
    	res, count, err := db.
    		From("profiles").
    		Select("*", "", false). // also tried specifying columns
    		ExecuteString()
    
    	spew.Dump(res, count, err)
    
    	if err != nil {
    		t.Fatalf("error returned: %v", err)
    	}
    
    	if res == "[]" || res == "" {
    		t.Fatalf("no result")
    	}
    }
    
    === RUN   TestSelect
    (string) (len=2) "[]"
    (int64) 0
    (interface {}) <nil>
        select_test.go:30: no result
    --- FAIL: TestSelect (0.29s)
    
    help wanted question 
    opened by AlbinoGeek 3
  • Define and Creating test cases with explanatory comments

    Define and Creating test cases with explanatory comments

    We must define test cases first. I think we can look other supabase postgREST libraries for this.

    Bellow I will add cases and addition status with tasklist style so this issue will more useful in tasklist.

    TEST DEFINITIONS

    • [x] Basic from/select without auth based here
    • [ ] Basic insert/upsert/update/delete based here
    opened by yusufpapurcu 0
Releases(v0.0.7)
  • v0.0.7(May 15, 2022)

    What's Changed

    • Reassign transformer methods to FilterBuilder by @boatilus in https://github.com/supabase-community/postgrest-go/pull/25

    Full Changelog: https://github.com/supabase-community/postgrest-go/compare/v0.0.6...v0.0.7

    Source code(tar.gz)
    Source code(zip)
  • v0.0.6(Jan 19, 2022)

  • v0.0.5(Jan 12, 2022)

    What's Changed

    • New execute method for json objects by @aaronschweig in https://github.com/supabase-community/postgrest-go/pull/10
    • In cases of non 20x responses, return an error from Execute() by @intabulas in https://github.com/supabase-community/postgrest-go/pull/11
    • fix: parsing of In filters by @darora in https://github.com/supabase-community/postgrest-go/pull/13
    • Add support for returning row count by @boatilus in https://github.com/supabase-community/postgrest-go/pull/23

    New Contributors

    • @aaronschweig made their first contribution in https://github.com/supabase-community/postgrest-go/pull/10
    • @intabulas made their first contribution in https://github.com/supabase-community/postgrest-go/pull/11
    • @boatilus made their first contribution in https://github.com/supabase-community/postgrest-go/pull/23

    Full Changelog: https://github.com/supabase-community/postgrest-go/compare/v.0.0.2...v0.0.5

    Source code(tar.gz)
    Source code(zip)
  • v0.0.3(Jul 30, 2021)

    PR #10: New execute method for json objects. @aaronschweig PR #11: In cases of non 20x responses, return an error from Execute(). @intabulas PR #13: fix: parsing of In filters. @darora PR #14: feat: avoid mutating shared state. @darora

    Source code(tar.gz)
    Source code(zip)
  • v.0.0.2(Jun 10, 2021)

Owner
Supabase Community
Supabase Community
Couchbase client in Go

A smart client for couchbase in go This is a unoffical version of a Couchbase Golang client. If you are looking for the Offical Couchbase Golang clien

null 316 Jun 26, 2022
Go client library for Pilosa

Go Client for Pilosa Go client for Pilosa high performance distributed index. What's New? See: CHANGELOG Requirements Go 1.12 and higher. Install Down

Pilosa 53 Jun 9, 2022
Golang client for redislabs' ReJSON module with support for multilple redis clients (redigo, go-redis)

Go-ReJSON - a golang client for ReJSON (a JSON data type for Redis) Go-ReJSON is a Go client for ReJSON Redis Module. ReJSON is a Redis module that im

Nitish Malhotra 268 Jun 5, 2022
redis client implement by golang, inspired by jedis.

godis redis client implement by golang, refers to jedis. this library implements most of redis command, include normal redis command, cluster command,

piaohao 104 Jun 21, 2022
Go Memcached client library #golang

About This is a memcache client library for the Go programming language (http://golang.org/). Installing Using go get $ go get github.com/bradfitz/gom

Brad Fitzpatrick 1.5k Jun 26, 2022
Neo4j Rest API Client for Go lang

neo4j.go Implementation of client package for communication with Neo4j Rest API. For more information and documentation please read Godoc Neo4j Page s

Cihangir 27 Jan 26, 2022
Neo4j REST Client in golang

DEPRECATED! Consider these instead: https://github.com/johnnadratowski/golang-neo4j-bolt-driver https://github.com/go-cq/cq Install: If you don't ha

null 76 Mar 14, 2022
Neo4j client for Golang

neoism - Neo4j client for Go Package neoism is a Go client library providing access to the Neo4j graph database via its REST API. Status System Status

Jason McVetta 386 Apr 6, 2022
Go client for Redis

Redigo Redigo is a Go client for the Redis database. Features A Print-like API with support for all Redis commands. Pipelining, including pipelined tr

null 9.2k Jun 24, 2022
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

null 14.8k Jul 1, 2022
Go Redis Client

xredis Built on top of github.com/garyburd/redigo with the idea to simplify creating a Redis client, provide type safe calls and encapsulate the low l

Raed Shomali 18 Jan 23, 2022
godis - an old Redis client for Go

godis Implements a few database clients for Redis. There is a stable client and an experimental client, redis and exp, respectively. To use any of the

Simon Zimmermann 86 Apr 16, 2022
Google Go Client and Connectors for Redis

Go-Redis Go Clients and Connectors for Redis. The initial release provides the interface and implementation supporting the (~) full set of current Red

Joubin Houshyar 441 Jun 15, 2022
Redis client library for Go

go-redis go-redis is a Redis client library for the Go programming language. It's built on the skeleton of gomemcache. It is safe to use by multiple g

Alexandre Fiori 45 Jul 15, 2020
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

null 14.8k Jun 30, 2022
Redis client Mock Provide mock test for redis query

Redis client Mock Provide mock test for redis query, Compatible with github.com/go-redis/redis/v8 Install Confirm that you are using redis.Client the

null 120 Jun 22, 2022
GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right away.

GoBigdis GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right

Riccardo 5 Apr 27, 2022
HDFS for Go - This is a native golang client for hdfs.

HDFS for Go This is a native golang client for hdfs. It connects directly to the namenode using the protocol buffers API. It tries to be idiomatic by

Colin Marc 1.2k Jun 15, 2022
PostgreSQL API Client

PostgreSQL API language search PostgreSQL API functions response: We don't use PostgreSQL in the usual way. We do everything through API functions, wh

Derek Sivers 14 May 9, 2022