# Skybridge FaaS Client A lightweight Go client library for interacting with the Skybridge Function-as-a-Service (FaaS) platform. ## Installation ```bash go get github.com/RyanCopley/skybridge/faas-client ``` ## Usage ### Basic Client Setup ```go 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 ```go // 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 ```go 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 ```go 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 ```go 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 ```go 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 ```go err := client.DeleteFunction(context.Background(), functionID) if err != nil { log.Fatal(err) } ``` ### Function Deployment ```go // 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 ```go 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 ```go 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 ```go 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 ```go // 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 ```go err := client.CancelExecution(context.Background(), executionID) if err != nil { log.Fatal(err) } ``` #### Getting Execution Logs ```go 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 ```go 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: ```go 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