Skip to main content

Queries

A query is implemented as a method on a workflow struct.

example.go
package example

import (
examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/workflow"
)

type HelloWorkflow struct {
*examplev1.HelloWorkflowInput
}

func (w *HelloWorkflow) Execute(ctx workflow.Context) (*examplev1.HelloOutput, error) {
workflow.GetLogger(ctx).Info("executing hello workflow", "input", w.Req)
return &examplev1.HelloOutput{}, nil
}

func (w *HelloWorkflow) GetHelloStatus(input *examplev1.GetHelloStatusInput) (*examplev1.GetHelloStatusOutput, error) {
return &examplev1.GetHelloStatusOutput{
Status: w.Req.GetStatus(),
}, nil
}

Parameters

Query definitions can omit an input parameter by specifying the native google.protobuf.Empty message type in its place. This requires an additional google/protobuf/empty.proto protobuf import.

warning

Query definitions must specify a non-empty output parameter.

example.go
package example

import (
examplev1 "path/to/gen/example/v1"
"go.temporal.io/sdk/workflow"
)

type HelloWorkflow struct {
*examplev1.HelloWorkflowInput
}

func (w *HelloWorkflow) Execute(ctx workflow.Context) (*examplev1.HelloOutput, error) {
workflow.GetLogger(ctx).Info("executing hello workflow", "input", w.Req)
return &examplev1.HelloOutput{}, nil
}

func (w *HelloWorkflow) GetHelloStatus() (*examplev1.GetHelloStatusOutput, error) {
return &examplev1.GetHelloStatusOutput{
Status: w.Req.GetStatus(),
}, nil
}

Invocation

The plugin supports several methods for executing protobuf queries, each of which is outlined in more detail below.

Client

Consumers can utilize the generated Client to execute queries from any Go application. See the Clients guide for more usage details.

main.go
package main

import (
"context"
"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 client: %v", err)
}

// initialize temporal protobuf client
ctx, client := context.Background(), examplev1.NewExampleClient(c)

// execute an example.v1.Example.GetHelloStatus query
// via workflow ID
status, err := client.GetHelloStatus(ctx, "wf-id", "", &examplev1.GetHelloStatusInput{})
if err != nil {
log.Fatalf("error executing example.v1.Example.GetHelloStatus query: %v", err)
}

// or use the corresponding query method defined on the
// workflow run
run, err := client.HelloAsync(ctx, &examplev1.HelloInput{})
if err != nil {
log.Fatalf("error starting example.v1.Example.Hello workflow: %v", err)
}
status, err = run.GetHelloStatus(&examplev1.GetHelloStatusInput{})
if err != nil {
log.Fatalf("error executing example.v1.Example.GetHelloStatus query: %v", err)
}
}

Command Line Interface

Consumers can utilize the generated Command Line Interface as a standalone application for executing queries. See the CLI guide for more usage details.

example -h
NAME:
example - an example temporal cli

USAGE:
example [global options] command [command options] [arguments...]

COMMANDS:
help, h Shows a list of commands or help for one command
QUERIES:
get-hello-status GetHelloStatus retrieves the status of a Hello workflow
WORKFLOWS:
hello Hello returns a friendly greeting
example get-hello-status -h
NAME:
example get-hello-status - GetHelloStatus retrieves the status of a Hello workflow

USAGE:
example get-hello-status [command options] [arguments...]

CATEGORY:
WORKFLOWS

OPTIONS:
--help, -h show help
--input-file value, -f value path to json-formatted input file
--run-id value, -r value run id
--workflow-id value, -w value workflow id

INPUT

--format value // Format specifies the output format
example get-hello-status -w foo --format json
{
"result": "..."
}

Cross-Namespace (XNS)

Queries can be executed from other workflows in a different Temporal namespace or even an entirely separate Temporal cluster (e.g. on-prem to cloud). See the Cross-Namespace guide for more usage details.

example.go
package example

import (
"fmt"

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

func MyWorkflow(ctx workflow.Context) error {
run, err := examplev1xns.HelloAsync(ctx, &examplev1.HelloInput{})
if err != nil {
return fmt.Errorf("error starting example.v1.Example.Hello xns workflow: %w", err)
}

status, err := run.GetHelloStatus(ctx, &examplev1.GetHelloStatusInput{})
if err != nil {
return fmt.Errorf("error querying workflow: %w", err)
}

_, err = run.Get(ctx)
return err
}