Skip to content

InSelfControll/convex-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

convex-go

Pure-Go HTTP client for Convex backend, replicating the network behavior of Convex's legacy Python http_client.py.

Features

  • Pure Go - Uses only standard library (net/http, encoding/json)
  • No CGO - No WebSockets, no third-party HTTP libraries
  • Thread-safe - Safe for concurrent use across goroutines
  • Context support - Full cancellation and timeout support
  • Generics - Type-safe response unmarshaling with Go 1.18+
  • Complete value encoding - Supports Int64, bytes, special floats (NaN, Inf)
  • Both error types - ConvexError and ConvexExecutionError

Installation

go get github.com/inselfcontroll/convex-go

Usage

Basic Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    convex "github.com/inselfcontroll/convex-go"
)

func main() {
    // Create client
    client := convex.NewClient("https://your-deployment.convex.cloud", nil)
    client.SetAuth("your-convex-token")

    // Context with timeout
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // Define your result type
    type User struct {
        ID    string `json:"id"`
        Name  string `json:"name"`
        Email string `json:"email"`
    }

    // Execute query
    user, err := convex.Query[User](ctx, client, "users:getById", map[string]any{
        "id": "user123",
    })
    if err != nil {
        // Check for Convex function error
        if convexErr, ok := convex.IsConvexError(err); ok {
            log.Printf("Convex error: %s", convexErr.Message)
        } else {
            log.Printf("Request failed: %v", err)
        }
        return
    }

    fmt.Printf("User: %+v\n", user)
}

Authentication

// Standard Bearer token (typical for client requests)
client.SetAuth("your-convex-token")

// Admin key (for administrative operations)
client.SetAdminAuth("your-admin-key")

// Clear authentication
client.ClearAuth()

Queries, Mutations, and Actions

// Query (read-only)
result, err := convex.Query[MyType](ctx, client, "module:queryFunc", args)

// Mutation (can modify data)
result, err := convex.Mutation[MyType](ctx, client, "module:mutationFunc", args)

// Action (can perform side effects like external API calls)
result, err := convex.Action[MyType](ctx, client, "module:actionFunc", args)

Error Handling

Convex returns HTTP 200 even for function errors. Two error types are supported:

result, err := convex.Query[MyType](ctx, client, "myFunc", args)
if err != nil {
    // 1. ConvexError - function threw an error
    if convexErr, ok := convex.IsConvexError(err); ok {
        fmt.Println("Error message:", convexErr.Message)
        
        // Unmarshal error data if needed
        var errData MyErrorType
        if err := convexErr.UnmarshalData(&errData); err != nil {
            // Use errData
        }
        return
    }
    
    // 2. ConvexExecutionError - unexpected execution error
    if execErr, ok := convex.IsConvexExecutionError(err); ok {
        fmt.Println("Execution error:", execErr.Message)
        return
    }
    
    // Other errors (network, parsing, etc.)
    log.Printf("Request failed: %v", err)
}

Special Value Types

Convex has special handling for some types:

// Int64 (BigInt in JavaScript) - integers outside safe float range
bigInt := convex.NewInt64(9007199254740993) // 2^53 + 1

result, err := convex.Query[any](ctx, client, "math:bigIntOp", map[string]any{
    "value": bigInt,
})

// Bytes are automatically base64 encoded/decoded
data := []byte{0x00, 0x01, 0x02}
result, err := convex.Mutation[any](ctx, client, "files:upload", map[string]any{
    "data": data,
})

Debug Mode

Enable debug mode to print server log lines (only works on development deployments):

client.SetDebug(true)

Debug output is now safer by default:

  • Sensitive values in common patterns (e.g. Authorization, token, secret, api_key, password) are redacted.
  • Very large debug output is truncated to prevent log flooding.

Custom HTTP Client

httpClient := &http.Client{
    Timeout: 60 * time.Second,
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 100,
    },
}

client := convex.NewClient("https://your-deployment.convex.cloud", httpClient)

Security Defaults and Backward Compatibility

  • https:// is required by default for non-loopback hosts.
  • http://localhost and loopback HTTP addresses are still allowed for local development.
  • For backward compatibility with legacy remote http:// usage, you can explicitly opt in:
client.SetAllowInsecureHTTP(true)

This opt-in exists for migration compatibility and should only be used on trusted networks.

Architecture

This package follows the TTC (Tasks-Tools-Codebase) Pattern:

src/
├── codebase/       # Public API assembly layer
│   ├── client.go
│   ├── api.go
│   ├── errors.go
│   └── values.go
├── tasks/          # Business logic layer
│   ├── query.go
│   ├── mutation.go
│   ├── action.go
│   ├── errors.go
│   ├── result.go
│   └── observability.go
├── tools/          # Infrastructure layer
│   ├── client.go
│   ├── transport.go
│   └── types.go
└── values/         # Convex value encoding/decoding
    ├── types.go
    ├── encode.go
    └── decode.go

Testing

go test -v ./...

License

MIT

About

Pure-Go HTTP client for Convex.dev backend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages