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
}