postgrest-go Golang Client

repository·main·Indexed 42 days ago

https://github.com/supabase-community/postgrest-go

A Golang client for PostgREST providing an ORM-like restful interface for interacting with PostgreSQL databases. It supports CRUD operations, advanced filtering, full-text search, and Remote Procedure Calls (RPC). The library offers a stable release (v0.0.12) and a modern main branch featuring generics, structured responses, and context-aware Execute methods.

Tokens
11.6K
Snippets
56
Records
59
Agent score
52%

What's inside postgrest-go

  1. Compare postgrest-go API versions

    main

    The library has two primary API surfaces depending on your installation method. The main branch is recommended for modern Go development as it supports generics, structured responses, and context.Context in Execute methods.

    | Install command | API | 
    | --- | --- | 
    | `go get github.com/supabase-community/postgrest-go` | **v0.0.12** — `Select(columns, count, head)`, `Execute()` returns `([]byte, int64, error)` | 
    | `go get github.com/supabase-community/postgrest-go@main` | **main** — `Select(columns, opts)`, `Execute(ctx)` returns `*PostgrestResponse` |
  2. Retrieve a single result

    main

    When you expect exactly one row, use Single() or MaybeSingle(). Single() will return an error if no row is found, while MaybeSingle() is safer if the row might not exist.

    // Get a single row
    response, err := client.
    	From("users").
    	Select("*", nil).
    	Eq("id", 1).
    	Limit(1, nil).
    	Single().
    	Execute(context.Background())
    
    // Get a single row or null (maybeSingle)
    response, err = client.
    	From("users").
    	Select("*", nil).
    	Eq("id", 999).
    	MaybeSingle().
    	Execute(context.Background())
  3. Install postgrest-go

    main

    To install the library, use the standard Go get command. Note that there are two distinct versions available depending on whether you want the stable tagged release or the latest features from the main branch.

    # Install the latest tagged release (v0.0.12)
    go get github.com/supabase-community/postgrest-go
    
    # Install the main branch (includes generics and context-aware Execute)
    go get github.com/supabase-community/postgrest-go@main
  4. Perform CRUD operations (main branch)

    main

    The following examples demonstrate how to perform standard database operations using the main branch API.

    // Select with filters
    opts := &postgrest.SelectOptions{Count: "exact"}
    response, err := client.
    	From("users").
    	Select("id, name, email", opts).
    	Eq("status", "active").
    	Limit(10, nil).
    	Order("name", &postgrest.OrderOptions{Ascending: true}).
    	Execute(context.Background())
    
    // Insert a single row
    insertOpts := &postgrest.InsertOptions{Count: "exact"}
    response, err = client.
    	From("users").
    	Insert(map[string]interface{}{
    		"name":  "John Doe",
    		"email": "john@example.com",
    	}, insertOpts).
    	Execute(context.Background())
    
    // Update rows
    updateOpts := &postgrest.UpdateOptions{Count: "exact"}
    response, err = client.
    	From("users").
    	Update(map[string]interface{}{
    		"status": "inactive",
    	}, updateOpts).
    	Eq("id", 1).
    	Execute(context.Background())
    
    // Delete rows
    deleteOpts := &postgrest.DeleteOptions{Count: "exact"}
    response, err = client.
    	From("users").
    	Delete(deleteOpts).
    	Eq("status", "inactive").
    	Execute(context.Background())
    
    // Upsert (insert or update)
    upsertOpts := &postgrest.UpsertOptions{
    	OnConflict:      "email",
    	IgnoreDuplicates: false,
    	Count:           "exact",
    }
    response, err = client.
    	From("users").
    	Upsert(map[string]interface{}{
    		"email": "john@example.com",
    		"name":  "John Doe",
    	}, upsertOpts).
    	Execute(context.Background())
  5. Use advanced filtering and text search

    main

    The library provides a wide range of filter methods including logical operators, pattern matching, and full-text search.

    // Multiple filters
    response, err := client.
    	From("users").
    	Select("*", nil).
    	Eq("status", "active").
    	Gte("age", 18).
    	Lte("age", 65).
    	In("role", []interface{}{"admin", "user"}).
    	Like("name", "%John%").
    	Execute(context.Background())
    
    // Text search
    textSearchOpts := &postgrest.TextSearchOptions{
    	Type:   "websearch",
    	Config: "english",
    }
    response, err = client.
    	From("posts").
    	Select("*", nil).
    	TextSearch("content", "golang tutorial", textSearchOpts).
    	Execute(context.Background())
  6. Handle PostgREST errors

    main

    Errors can occur at two levels: network/parsing errors (returned by Execute) and PostgREST-specific database errors (contained within the PostgrestResponse.Error field).

    response, err := client.From("users").Select("*", nil).Execute(context.Background())
    if err != nil {
    	// Network or parsing error
    	panic(err)
    }
    
    if response.Error != nil {
    	// PostgREST error
    	fmt.Printf("Error: %s (Code: %s)\n", response.Error.Message, response.Error.Code)
    	fmt.Printf("Details: %s\n", response.Error.Details)
    	fmt.Printf("Hint: %s\n", response.Error.Hint)
    }
  7. Basic usage with v0.0.12

    main

    If you are using the stable tagged release (v0.0.12), the Select method takes three arguments and Execute returns the raw data, count, and error.

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    
    	"github.com/supabase-community/postgrest-go"
    )
    
    func main() {
    	client := postgrest.NewClient("http://localhost:3000/rest/v1", "public", nil)
    	if client.ClientError != nil {
    		panic(client.ClientError)
    	}
    
    	data, count, err := client.From("users").Select("*", "", false).Execute()
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Printf("count: %d\n", count)
    	fmt.Println(string(data))
    }
  8. Call a PostgreSQL function via RPC

    main

    Use the Rpc method to execute a stored procedure or function on the PostgreSQL server.

    // Call a PostgreSQL function
    rpcOpts := &postgrest.RpcOptions{Count: "exact"}
    response, err := client.
    	Rpc("get_user_by_email", map[string]interface{}{
    		"email": "john@example.com",
    	}, rpcOpts).
    	Execute(context.Background())
  9. Unmarshal results directly into a struct with ExecuteTo

    main

    Instead of manually unmarshaling response.Data, use ExecuteTo to unmarshal the query results directly into a slice of structs or a single struct.

    type User struct {
    	ID    int64  `json:"id"`
    	Name  string `json:"name"`
    	Email string `json:"email"`
    }
    
    var users []User
    count, err := client.
    	From("users").
    	Select("*", nil).
    	Eq("status", "active").
    	ExecuteTo(context.Background(), &users)
  10. Basic usage with main branch

    main

    The main branch uses a more modern API. Select takes two arguments, and Execute requires a context.Context. Results are returned in a PostgrestResponse object.

    package main
    
    import (
    	"context"
    	"encoding/json"
    	"fmt"
    
    	"github.com/supabase-community/postgrest-go"
    )
    
    func main() {
    	// Create a new client
    	client := postgrest.NewClient("http://localhost:3000/rest/v1", "public", nil)
    	if client.ClientError != nil {
    		panic(client.ClientError)
    	}
    
    	// Select data
    	response, err := client.From("users").Select("*", nil).Execute(context.Background())
    	if err != nil {
    		panic(err)
    	}
    
    	if response.Error != nil {
    		panic(response.Error)
    	}
    
    	// Print results
    	data, _ := json.Marshal(response.Data)
    	fmt.Println(string(data))
    }
  11. Configure PostgREST via Docker Compose environment variables

    main

    When running PostgREST using the provided Docker Compose configuration, you can control its behavior using several PGRST_* environment variables. These settings define how PostgREST connects to the database, which schemas it exposes, and how it handles authentication.

    services:
      rest:
        image: postgrest/postgrest:latest
        environment:
          PGRST_DB_URI: postgres://postgres:postgres@db:5432/postgres
          PGRST_DB_SCHEMA: public, personal
          PGRST_DB_ANON_ROLE: postgres
          PGRST_JWT_SECRET: "reallyreallyreallyreallyverysafe"