grpc/

directory
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2025 License: MIT

README

gRPC Function Examples

This directory contains examples of creating and invoking serverless functions via gRPC.

Basic gRPC Function

The basic directory contains a simple gRPC function that returns a greeting message.

// Function that returns a greeting message
func (h *FunctionHandler) Execute(input map[string]interface{}) (interface{}, error) {
    name := "World"
    if n, ok := input["name"].(string); ok {
        name = n
    }
    return map[string]interface{}{
        "message": fmt.Sprintf("Hello, %s from gRPC!", name),
    }, nil
}
Invoking the Function
# Deploy the function
mkdir -p functions/grpc-basic
cp examples/grpc/basic/main.go functions/grpc-basic/main.go

# Invoke via gRPC client
go run examples/grpc/client/main.go -function grpc-basic -input '{"name": "John"}'
# Output: {"message": "Hello, John from gRPC!"}

Complex Data Types

The complex-data directory contains a function that handles complex data types.

// Function that handles complex data types
func (h *FunctionHandler) Execute(input map[string]interface{}) (interface{}, error) {
    // Extract nested data
    user, ok := input["user"].(map[string]interface{})
    if !ok {
        return nil, errors.New("user data is required")
    }

    // Extract array data
    items, ok := input["items"].([]interface{})
    if !ok {
        return nil, errors.New("items array is required")
    }

    // Process the data
    return map[string]interface{}{
        "user_processed": map[string]interface{}{
            "name": user["name"],
            "id": user["id"],
        },
        "item_count": len(items),
        "items_processed": items,
    }, nil
}
Invoking the Function
# Deploy the function
mkdir -p functions/grpc-complex
cp examples/grpc/complex-data/main.go functions/grpc-complex/main.go

# Invoke via gRPC client
go run examples/grpc/client/main.go -function grpc-complex -input '{"user": {"name": "John", "id": 123}, "items": ["item1", "item2", "item3"]}'

Error Handling

The error-handling directory contains a function that demonstrates error handling in gRPC.

// Function that demonstrates error handling
func (h *FunctionHandler) Execute(input map[string]interface{}) (interface{}, error) {
    // Check if required fields are present
    if _, ok := input["action"]; !ok {
        return nil, errors.New("action field is required")
    }

    action := input["action"].(string)

    switch action {
    case "success":
        return map[string]interface{}{
            "status": "success",
            "message": "Operation completed successfully",
        }, nil
    case "error":
        return nil, errors.New("operation failed")
    default:
        return nil, fmt.Errorf("unknown action: %s", action)
    }
}
Invoking the Function
# Deploy the function
mkdir -p functions/grpc-error
cp examples/grpc/error-handling/main.go functions/grpc-error/main.go

# Invoke with success action
go run examples/grpc/client/main.go -function grpc-error -input '{"action": "success"}'

# Invoke with error action
go run examples/grpc/client/main.go -function grpc-error -input '{"action": "error"}'

gRPC Client

The client directory contains a simple gRPC client for invoking functions.

package main

import (
    "context"
    "encoding/json"
    "flag"
    "fmt"
    "log"
    "time"

    pb "github.com/mstgnz/self-hosted-serverless/internal/grpc/proto"
    "google.golang.org/grpc"
)

func main() {
    // Parse command line arguments
    functionName := flag.String("function", "", "Function name to execute")
    inputJSON := flag.String("input", "{}", "Input JSON")
    flag.Parse()

    // Connect to the gRPC server
    conn, err := grpc.Dial("localhost:9090", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer conn.Close()

    // Create a client
    client := pb.NewFunctionServiceClient(conn)

    // Parse input JSON
    var input map[string]string
    if err := json.Unmarshal([]byte(*inputJSON), &input); err != nil {
        log.Fatalf("Failed to parse input JSON: %v", err)
    }

    // Execute the function
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    resp, err := client.ExecuteFunction(ctx, &pb.ExecuteFunctionRequest{
        Name:  *functionName,
        Input: input,
    })

    if err != nil {
        log.Fatalf("Error executing function: %v", err)
    }

    // Print the result
    fmt.Printf("Result: %v\n", resp.Result)
}
Using the Client
# Build the client
go build -o grpc-client examples/grpc/client/main.go

# Invoke a function
./grpc-client -function grpc-basic -input '{"name": "John"}'

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL