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

297 lines
6.6 KiB
Markdown

# 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