> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cocobase.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Go SDK

> Complete guide to using Cocobase with Go

# Go SDK

Complete guide to using Cocobase with Go applications.

## Installation

```bash theme={null}
go get github.com/lordace-coder/cocobase-go
```

## Quick Start

### Initialize Cocobase

```go theme={null}
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/lordace-coder/cocobase-go/cocobase"
)

func main() {
    client := cocobase.NewClient(cocobase.Config{
        APIKey:  "YOUR_API_KEY",
        BaseURL: "https://api.cocobase.cc", // Optional
    })

    ctx := context.Background()
    _ = ctx // use ctx in your operations
}
```

```go theme={null}
// With custom storage (for token persistence)
import "github.com/lordace-coder/cocobase-go/storage"

store := storage.NewMemoryStorage()
// Or file-based:
// store, _ := storage.NewFileStorage(".cocobase/storage.json")

client := cocobase.NewClient(cocobase.Config{
    APIKey:  "YOUR_API_KEY",
    Storage: store,
})
```

### Basic Operations

```go theme={null}
// List documents (no filters)
docs, err := client.ListDocuments(ctx, "posts", nil)

// List with query
query := cocobase.NewQuery().Where("status", "active").Limit(20)
docs, err := client.ListDocuments(ctx, "posts", query)

// Get single document
doc, err := client.GetDocument(ctx, "posts", "doc-id")

// Create document
created, err := client.CreateDocument(ctx, "posts", map[string]interface{}{
    "title":   "My First Post",
    "content": "Hello World!",
})

// Update document
updated, err := client.UpdateDocument(ctx, "posts", "doc-id", map[string]interface{}{
    "title": "Updated Title",
})

// Delete document
err = client.DeleteDocument(ctx, "posts", "doc-id")
```

***

## Querying Data

### Simple Filters

```go theme={null}
query := cocobase.NewQuery().Where("status", "active")
docs, err := client.ListDocuments(ctx, "users", query)
```

### Comparison Operators

```go theme={null}
query := cocobase.NewQuery().
    Filter("age", "gte", 18).
    Filter("age", "lte", 65)
```

### String Operations

```go theme={null}
query := cocobase.NewQuery().
    Filter("email", "endswith", "gmail.com")
```

### IN Operator

```go theme={null}
query := cocobase.NewQuery().
    Filter("role", "in", "admin,moderator,support")
```

### NULL Checks

```go theme={null}
query := cocobase.NewQuery().
    Filter("deletedAt", "isnull", true)
```

### Simple OR

```go theme={null}
query := cocobase.NewQuery().
    Where("status", "active").
    Or("isPremium", "eq", true).
    Or("isVerified", "eq", true)
```

### Named OR Groups

```go theme={null}
query := cocobase.NewQuery().
    OrGroup("tier", "isPremium", "eq", true).
    OrGroup("tier", "isVerified", "eq", true).
    OrGroup("location", "country", "eq", "US").
    OrGroup("location", "country", "eq", "UK")
```

### Multi-Field Search

```go theme={null}
query := cocobase.NewQuery().
    MultiFieldOr([]string{"name", "email"}, "contains", "john")
```

### Sorting and Pagination

```go theme={null}
query := cocobase.NewQuery().
    Where("status", "active").
    Sort("createdAt").
    OrderDesc().
    Limit(50).
    Offset(100)

docs, err := client.ListDocuments(ctx, "users", query)
```

***

## Working with Structs

### Define Your Types

```go theme={null}
type Book struct {
    Title       string  `json:"title"`
    Author      string  `json:"author"`
    Price       float64 `json:"price"`
    PublishedAt string  `json:"publishedAt,omitempty"`
}
```

### Create with Structs

```go theme={null}
newBook := Book{
    Title:  "Clean Code",
    Author: "Robert Martin",
    Price:  45.99,
}

created, err := client.CreateDocument(ctx, "books", newBook)
```

### Parse Response to Struct

```go theme={null}
doc, err := client.GetDocument(ctx, "books", "doc-id")
if err != nil {
    log.Fatal(err)
}

var book Book
err = doc.DataAs(&book)
if err != nil {
    log.Fatal(err)
}

fmt.Println(book.Title)
```

***

## Authentication

### Initialize Auth (restore session from storage)

```go theme={null}
err := client.InitAuth(ctx)
```

### Register

```go theme={null}
err := client.Register(ctx, "user@example.com", "password123", map[string]interface{}{
    "firstName": "John",
    "lastName":  "Doe",
})
// Pass nil for no extra data:
// err := client.Register(ctx, "user@example.com", "password123", nil)
```

### Login

```go theme={null}
err = client.Login(ctx, "user@example.com", "password123")
```

### Get Current User

```go theme={null}
user, err := client.GetCurrentUser(ctx)
fmt.Println("User ID:", user.ID)
fmt.Println("Email:", user.Email)
```

### Update User

```go theme={null}
newEmail := "new@example.com"
user, err = client.UpdateUser(ctx, map[string]interface{}{
    "phone": "+1234567890",
}, &newEmail, nil)
```

### Logout

```go theme={null}
err = client.Logout()
```

### Check Authentication

```go theme={null}
if client.IsAuthenticated() {
    fmt.Println("User is logged in")
}
```

### Check Role

```go theme={null}
if client.HasRole("admin") {
    fmt.Println("User is an admin")
}
```

***

## Real-time Data

### Watch a Collection

```go theme={null}
conn, err := client.WatchCollection(ctx, "posts", func(event cocobase.Event) {
    fmt.Printf("Event: %s\n", event.Event)
    fmt.Printf("Data: %+v\n", event.Data)
}, "posts-watcher") // last param is connection name (optional label)

if err != nil {
    log.Fatal(err)
}

// Close when done
defer conn.Close()
```

***

## Error Handling

```go theme={null}
doc, err := client.GetDocument(ctx, "posts", "non-existent-id")
if err != nil {
    var apiErr *cocobase.APIError
    if errors.As(err, &apiErr) {
        fmt.Println("Status:", apiErr.StatusCode)
        fmt.Println("Error:", apiErr.Body)
    } else {
        fmt.Println("Error:", err)
    }
}
```

***

## Context Support

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

doc, err := client.GetDocument(ctx, "posts", "doc-id")
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        fmt.Println("Request timed out")
    }
}
```

***

## Best Practices

### 1. Use Structs for Type Safety

```go theme={null}
// Good
type Post struct {
    Title   string `json:"title"`
    Content string `json:"content"`
}

var post Post
doc.DataAs(&post)

// Avoid
data := doc.Data.(map[string]interface{})
```

### 2. Always Handle Errors

```go theme={null}
doc, err := client.GetDocument(ctx, "posts", id)
if err != nil {
    return nil, fmt.Errorf("failed to get post: %w", err)
}
```

### 3. Use Environment Variables

```go theme={null}
client := cocobase.NewClient(cocobase.Config{
    APIKey: os.Getenv("COCOBASE_API_KEY"),
})
```

### 4. Always Set Limits

```go theme={null}
// Good
query := cocobase.NewQuery().Limit(20)
docs, err := client.ListDocuments(ctx, "posts", query)

// Bad - could return thousands
docs, err := client.ListDocuments(ctx, "posts", nil)
```

***

## Next Steps

* [JavaScript SDK](/sdk-reference/javascript) - Learn about the JS/TS SDK
* [Flutter SDK](/sdk-reference/flutter) - Learn about the Flutter SDK
* [Authentication](/core-concepts/authentication) - Deep dive into auth
* [Querying](/features/querying) - Advanced query techniques
