Skip to content

Instantly share code, notes, and snippets.

@jhahspu
Last active February 8, 2025 15:28
Show Gist options
  • Save jhahspu/9656d010b48a3b7f243c26b844f22dd0 to your computer and use it in GitHub Desktop.
Save jhahspu/9656d010b48a3b7f243c26b844f22dd0 to your computer and use it in GitHub Desktop.
Supabase
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
)

// Movie represents a row in the Movies table
type Movie struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
}

func main() {
	// Replace with your Supabase URL and API key
	supabaseUrl := "https://your-supabase-url.supabase.co/rest/v1"
	supabaseKey := "your-supabase-api-key"

	// Authenticate a user and get their JWT token
	userToken, err := signInUser(supabaseUrl, supabaseKey, "[email protected]", "password")
	if err != nil {
		log.Fatalf("Error signing in user: %v", err)
	}

	// Fetch all rows from the Movies table using the user's JWT token
	movies, err := fetchMovies(supabaseUrl, supabaseKey, userToken)
	if err != nil {
		log.Fatalf("Error fetching movies: %v", err)
	}

	// Print the fetched movies
	fmt.Println("Movies:")
	for _, movie := range movies {
		fmt.Printf("ID: %d, Title: %s\n", movie.ID, movie.Title)
	}
}

// signInUser authenticates a user and returns their JWT token
func signInUser(supabaseUrl, supabaseKey, email, password string) (string, error) {
	// Construct the URL for the sign-in endpoint
	url := fmt.Sprintf("%s/auth/v1/token?grant_type=password", supabaseUrl)

	// Create the request body
	body := map[string]string{
		"email":    email,
		"password": password,
	}
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return "", fmt.Errorf("failed to marshal request body: %w", err)
	}

	// Create a new HTTP POST request
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyBytes))
	if err != nil {
		return "", fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
	req.Header.Set("apikey", supabaseKey)
	req.Header.Set("Content-Type", "application/json")

	// Send the request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	// Read the response body
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("failed to read response body: %w", err)
	}

	// Check the response status code
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unexpected status code: %d, response: %s", resp.StatusCode, string(respBody))
	}

	// Parse the response to get the JWT token
	var result map[string]interface{}
	if err := json.Unmarshal(respBody, &result); err != nil {
		return "", fmt.Errorf("failed to unmarshal response: %w", err)
	}

	token, ok := result["access_token"].(string)
	if !ok {
		return "", fmt.Errorf("failed to extract JWT token from response")
	}

	return token, nil
}

// fetchMovies fetches all rows from the Movies table using the Supabase REST API
func fetchMovies(supabaseUrl, supabaseKey, userToken string) ([]Movie, error) {
	// Construct the URL for the Movies table
	url := fmt.Sprintf("%s/Movies?select=*", supabaseUrl)

	// Create a new HTTP GET request
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	// Set headers
	req.Header.Set("apikey", supabaseKey)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", userToken))
	req.Header.Set("Content-Type", "application/json")

	// Send the request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	// Read the response body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("failed to read response body: %w", err)
	}

	// Print the raw response for debugging
	fmt.Println("Raw Response:", string(body))

	// Check the response status code
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status code: %d, response: %s", resp.StatusCode, string(body))
	}

	// Unmarshal the response into a slice of Movie structs
	var movies []Movie
	if err := json.Unmarshal(body, &movies); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response: %w", err)
	}

	return movies, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment