Skip to main content

Clients

The protoc-gen-go-temporal plugin generates comprehensive client libraries that provide type-safe interfaces for interacting with Temporal workflows. These clients wrap the standard Temporal Go SDK to provide structured access to workflow execution, signals, queries, and updates.

Client Interface​

Each protobuf service generates a client interface (e.g., ExampleClient) that provides methods for all workflow operations defined in your schema.

Generated Client Interface
type ExampleClient interface {
// Workflow execution methods
CreateFoo(ctx context.Context, req *CreateFooRequest, opts ...*CreateFooOptions) (*CreateFooResponse, error)
CreateFooAsync(ctx context.Context, req *CreateFooRequest, opts ...*CreateFooOptions) (CreateFooRun, error)
GetCreateFoo(ctx context.Context, workflowID, runID string) CreateFooRun

// Signal methods
SetFooProgress(ctx context.Context, workflowID, runID string, req *SetFooProgressRequest) error

// Query methods
GetFooProgress(ctx context.Context, workflowID, runID string) (*GetFooProgressResponse, error)

// Update methods
UpdateFooProgress(ctx context.Context, workflowID, runID string, req *SetFooProgressRequest, opts ...*UpdateFooProgressOptions) (*GetFooProgressResponse, error)
UpdateFooProgressAsync(ctx context.Context, workflowID, runID string, req *SetFooProgressRequest, opts ...*UpdateFooProgressOptions) (UpdateFooProgressHandle, error)

// Workflow management
CancelWorkflow(ctx context.Context, workflowID, runID string) error
TerminateWorkflow(ctx context.Context, workflowID, runID string, reason string, details ...any) error
}

Client Initialization​

Initialize a client by providing a Temporal client instance and optional configuration.

main.go
package main

import (
"log"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/client"
)

func main() {
// Initialize Temporal client
c, err := client.Dial(client.Options{})
if err != nil {
log.Fatalf("error initializing temporal client: %v", err)
}
defer c.Close()

// Initialize generated client
client := examplev1.NewExampleClient(c)

// Use client...
}

Workflow Execution​

Clients provide both synchronous and asynchronous methods for workflow execution.

Synchronous Execution​

Synchronous methods execute the workflow and block until completion.

main.go
package main

import (
"context"
"log"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/client"
)

func main() {
c, _ := client.Dial(client.Options{})
client := examplev1.NewExampleClient(c)

// Execute workflow synchronously - blocks until completion
result, err := client.CreateFoo(context.Background(), &examplev1.CreateFooRequest{
Name: "my-foo",
})
if err != nil {
log.Fatalf("workflow execution failed: %v", err)
}

log.Printf("workflow completed: %s", result.String())
}

Asynchronous Execution​

Asynchronous methods start the workflow and return immediately with a workflow run handle.

main.go
package main

import (
"context"
"log"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/client"
)

func main() {
c, _ := client.Dial(client.Options{})
client := examplev1.NewExampleClient(c)

// Start workflow asynchronously
run, err := client.CreateFooAsync(context.Background(), &examplev1.CreateFooRequest{
Name: "my-foo",
})
if err != nil {
log.Fatalf("workflow start failed: %v", err)
}

log.Printf("workflow started: id=%s, run_id=%s", run.ID(), run.RunID())

// Get result when ready
result, err := run.Get(context.Background())
if err != nil {
log.Fatalf("workflow execution failed: %v", err)
}

log.Printf("workflow completed: %s", result.String())
}

Workflow Run​

Workflow run handles provide access to workflow metadata and operations for running workflows.

Generated Run Interface
type CreateFooRun interface {
// Workflow metadata
ID() string
RunID() string
Run() client.WorkflowRun

// Result retrieval
Get(ctx context.Context) (*CreateFooResponse, error)

// Lifecycle management
Cancel(ctx context.Context) error
Terminate(ctx context.Context, reason string, details ...any) error

// Signal methods (if workflow defines signals)
SetFooProgress(ctx context.Context, req *SetFooProgressRequest) error

// Query methods (if workflow defines queries)
GetFooProgress(ctx context.Context) (*GetFooProgressResponse, error)

// Update methods (if workflow defines updates)
UpdateFooProgress(ctx context.Context, req *SetFooProgressRequest, opts ...*UpdateFooProgressOptions) (*GetFooProgressResponse, error)
UpdateFooProgressAsync(ctx context.Context, req *SetFooProgressRequest, opts ...*UpdateFooProgressOptions) (UpdateFooProgressHandle, error)
}

Signals​

Send signals to running workflows using client methods or workflow run handles.

main.go
func sendSignals(client examplev1.ExampleClient) {
ctx := context.Background()

// Send signal using client method
err := client.SetFooProgress(ctx, "workflow-id", "run-id", &examplev1.SetFooProgressRequest{
Progress: 50.0,
})
if err != nil {
log.Printf("signal failed: %v", err)
}
}

Queries​

Execute queries against running workflows to retrieve current state.

main.go
func executeQueries(client examplev1.ExampleClient) {
ctx := context.Background()

// Execute query using client method
progress, err := client.GetFooProgress(ctx, "workflow-id", "run-id")
if err != nil {
log.Printf("query failed: %v", err)
return
}

log.Printf("current progress: %.1f%%", progress.Progress)
}

Updates​

Execute updates to modify workflow state and receive return values.

main.go
func executeUpdates(client examplev1.ExampleClient) {
ctx := context.Background()

// Execute update synchronously - blocks until completion
result, err := client.UpdateFooProgress(ctx, "workflow-id", "run-id",
&examplev1.SetFooProgressRequest{Progress: 100.0})
if err != nil {
log.Printf("update failed: %v", err)
return
}

log.Printf("update completed: %.1f%%", result.Progress)
}

Signal-with-Start​

Execute workflows with an initial signal, allowing workflows to be started in a specific state.

main.go
package main

import (
"context"
"log"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/client"
)

func main() {
c, _ := client.Dial(client.Options{})
client := examplev1.NewExampleClient(c)
ctx := context.Background()

// Start workflow with initial signal
result, err := client.CreateFooWithSetFooProgress(ctx,
&examplev1.CreateFooRequest{Name: "test"},
&examplev1.SetFooProgressRequest{Progress: 25.0},
)
if err != nil {
log.Fatalf("signal-with-start failed: %v", err)
}

log.Printf("workflow completed with initial progress: %s", result.String())
}

Update-with-Start​

Execute workflows with an initial update, allowing workflows to be started and immediately updated atomically.

warning

Update-with-start is considered experimental.

main.go
package main

import (
"context"
"log"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/client"
)

func main() {
c, _ := client.Dial(client.Options{})
client := examplev1.NewExampleClient(c)
ctx := context.Background()

// Start workflow with initial update
updateResult, workflowRun, err := client.CreateFooWithUpdateFooProgress(ctx,
&examplev1.CreateFooRequest{Name: "test"},
&examplev1.SetFooProgressRequest{Progress: 50.0},
)
if err != nil {
log.Fatalf("update-with-start failed: %v", err)
}

log.Printf("workflow started with initial update: %s", updateResult.String())
log.Printf("workflow ID: %s", workflowRun.ID())

// Continue with workflow execution
finalResult, err := workflowRun.Get(ctx)
if err != nil {
log.Fatalf("workflow execution failed: %v", err)
}

log.Printf("workflow completed: %s", finalResult.String())
}

Options​

Configure workflow execution, updates, and other operations using the generated options builders.

Workflow Options​

main.go
package main

import (
"context"
"time"

examplev1 "path/to/gen/example/v1"
"go.temporal.io/api/enums/v1"
"go.temporal.io/sdk/temporal"
)

func executeWithOptions(client examplev1.ExampleClient) {
ctx := context.Background()

// Execute workflow with custom options
run, err := client.CreateFooAsync(ctx, &examplev1.CreateFooRequest{Name: "test"},
examplev1.NewCreateFooOptions().
WithID("custom-workflow-id").
WithExecutionTimeout(time.Hour * 2).
WithTaskQueue("custom-task-queue").
WithRetryPolicy(&temporal.RetryPolicy{
MaximumAttempts: 3,
}).
WithSearchAttributes(map[string]any{
"environment": "staging",
"team": "backend",
}).
WithIDReusePolicy(enums.WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE),
)
if err != nil {
log.Printf("workflow start failed: %v", err)
return
}

// Use run...
}

Update Options​

main.go
func executeUpdateWithOptions(run examplev1.CreateFooRun) {
ctx := context.Background()

// Execute update with custom options
result, err := run.UpdateFooProgress(ctx,
&examplev1.SetFooProgressRequest{Progress: 100.0},
examplev1.NewUpdateFooProgressOptions().
WithUpdateID("custom-update-id").
WithWaitPolicy(enums.UPDATE_WORKFLOW_EXECUTION_LIFECYCLE_STAGE_COMPLETED),
)
if err != nil {
log.Printf("update failed: %v", err)
return
}

log.Printf("update completed: %s", result.String())
}