Files
skybridge/faas-client
2025-08-31 17:19:13 -04:00
..
2025-08-31 17:19:13 -04:00
2025-08-31 17:19:13 -04:00
2025-08-31 17:19:13 -04:00
2025-08-31 17:19:13 -04:00
2025-08-31 17:19:13 -04:00

Skybridge FaaS Client

A lightweight Go client library for interacting with the Skybridge Function-as-a-Service (FaaS) platform.

Installation

go get github.com/RyanCopley/skybridge/faas-client

Usage

Basic Client Setup

package main

import (
    "context"
    "log"
    
    faasclient "github.com/RyanCopley/skybridge/faas-client"
)

func main() {
    // Create a new client
    client := faasclient.NewClient(
        "http://localhost:8080", // FaaS API base URL
        faasclient.WithUserEmail("admin@example.com"), // Authentication
    )
    
    // Use the client...
}

Authentication Options

// Using user email header (for development)
client := faasclient.NewClient(baseURL, 
    faasclient.WithUserEmail("user@example.com"))

// Using custom auth headers
client := faasclient.NewClient(baseURL,
    faasclient.WithAuth(map[string]string{
        "Authorization": "Bearer " + token,
        "X-User-Email":  "user@example.com",
    }))

// Using custom HTTP client
httpClient := &http.Client{Timeout: 30 * time.Second}
client := faasclient.NewClient(baseURL,
    faasclient.WithHTTPClient(httpClient))

Function Management

Creating a Function

req := &faasclient.CreateFunctionRequest{
    Name:    "my-function",
    AppID:   "my-app",
    Runtime: faasclient.RuntimeNodeJS18,
    Image:   "node:18-alpine", // Optional, auto-selected if not provided
    Handler: "index.handler",
    Code:    "exports.handler = async (event) => { return 'Hello World'; }",
    Environment: map[string]string{
        "NODE_ENV": "production",
    },
    Timeout: faasclient.Duration(30 * time.Second),
    Memory:  512,
    Owner: faasclient.Owner{
        Type:  faasclient.OwnerTypeIndividual,
        Name:  "John Doe",
        Owner: "john@example.com",
    },
}

function, err := client.CreateFunction(context.Background(), req)
if err != nil {
    log.Fatal(err)
}

log.Printf("Created function: %s (ID: %s)", function.Name, function.ID)

Getting a Function

function, err := client.GetFunction(context.Background(), functionID)
if err != nil {
    log.Fatal(err)
}

log.Printf("Function: %s, Runtime: %s", function.Name, function.Runtime)

Updating a Function

newTimeout := faasclient.Duration(60 * time.Second)
req := &faasclient.UpdateFunctionRequest{
    Timeout: &newTimeout,
    Environment: map[string]string{
        "NODE_ENV": "development",
    },
}

function, err := client.UpdateFunction(context.Background(), functionID, req)
if err != nil {
    log.Fatal(err)
}

Listing Functions

response, err := client.ListFunctions(context.Background(), "my-app", 50, 0)
if err != nil {
    log.Fatal(err)
}

for _, fn := range response.Functions {
    log.Printf("Function: %s (ID: %s)", fn.Name, fn.ID)
}

Deleting a Function

err := client.DeleteFunction(context.Background(), functionID)
if err != nil {
    log.Fatal(err)
}

Function Deployment

// Deploy with default options
resp, err := client.DeployFunction(context.Background(), functionID, nil)
if err != nil {
    log.Fatal(err)
}

// Force deployment
req := &faasclient.DeployFunctionRequest{
    Force: true,
}
resp, err = client.DeployFunction(context.Background(), functionID, req)
if err != nil {
    log.Fatal(err)
}

log.Printf("Deployment status: %s", resp.Status)

Function Execution

Synchronous Execution

input := json.RawMessage(`{"name": "World"}`)
req := &faasclient.ExecuteFunctionRequest{
    FunctionID: functionID,
    Input:      input,
    Async:      false,
}

response, err := client.ExecuteFunction(context.Background(), req)
if err != nil {
    log.Fatal(err)
}

log.Printf("Result: %s", string(response.Output))
log.Printf("Duration: %v", response.Duration)

Asynchronous Execution

input := json.RawMessage(`{"name": "World"}`)
response, err := client.InvokeFunction(context.Background(), functionID, input)
if err != nil {
    log.Fatal(err)
}

log.Printf("Execution ID: %s", response.ExecutionID)
log.Printf("Status: %s", response.Status)

Execution Management

Getting Execution Details

execution, err := client.GetExecution(context.Background(), executionID)
if err != nil {
    log.Fatal(err)
}

log.Printf("Status: %s", execution.Status)
log.Printf("Duration: %v", execution.Duration)
if execution.Error != "" {
    log.Printf("Error: %s", execution.Error)
}

Listing Executions

// List all executions
response, err := client.ListExecutions(context.Background(), nil, 50, 0)
if err != nil {
    log.Fatal(err)
}

// List executions for a specific function
response, err = client.ListExecutions(context.Background(), &functionID, 50, 0)
if err != nil {
    log.Fatal(err)
}

for _, exec := range response.Executions {
    log.Printf("Execution: %s, Status: %s", exec.ID, exec.Status)
}

Canceling an Execution

err := client.CancelExecution(context.Background(), executionID)
if err != nil {
    log.Fatal(err)
}

Getting Execution Logs

logs, err := client.GetExecutionLogs(context.Background(), executionID)
if err != nil {
    log.Fatal(err)
}

for _, logLine := range logs.Logs {
    log.Printf("Log: %s", logLine)
}

Getting Running Executions

response, err := client.GetRunningExecutions(context.Background())
if err != nil {
    log.Fatal(err)
}

log.Printf("Running executions: %d", response.Count)
for _, exec := range response.Executions {
    log.Printf("Running: %s (Function: %s)", exec.ID, exec.FunctionID)
}

Types

The client provides comprehensive type definitions that match the FaaS API:

  • FunctionDefinition - Complete function metadata
  • FunctionExecution - Execution details and results
  • RuntimeType - Supported runtimes (NodeJS18, Python39, Go120, Custom)
  • ExecutionStatus - Execution states (Pending, Running, Completed, Failed, etc.)
  • Owner - Ownership information
  • Request/Response types for all operations

Error Handling

The client provides detailed error messages that include HTTP status codes and response bodies:

function, err := client.GetFunction(ctx, nonExistentID)
if err != nil {
    // Error will include status code and details
    log.Printf("Error: %v", err) // "get function failed with status 404: Function not found"
}

Architecture Benefits

This client package is designed as a lightweight, standalone library that:

  • No heavy dependencies: Only requires google/uuid
  • Zero coupling: Doesn't import the entire FaaS service
  • Modular: Can be used by any service in your monolith
  • Type-safe: Comprehensive Go types for all API operations
  • Flexible auth: Supports multiple authentication methods