Verbs

Defining Verbs

To declare a Verb, write a normal Go function with the following signature, annotated with the Go comment directive //ftl:verb:

//ftl:verb
func F(context.Context, In) (Out, error) { }

eg.

type EchoRequest struct {}

type EchoResponse struct {}

//ftl:verb
func Echo(ctx context.Context, in EchoRequest) (EchoResponse, error) {
  // ...
}

To declare a Verb, write a normal Kotlin function with the following signature, annotated with the Kotlin annotation @Verb:

@Verb
fun F(In): Out { }

eg.

data class EchoRequest
data class EchoResponse

@Verb
fun echo(request: EchoRequest): EchoResponse {
  // ...
}

By default verbs are only visible to other verbs in the same module.

Calling Verbs

To call a verb, import the module's verb client ({ModuleName}.{VerbName}Client), add it to your verb's signature, then invoke it as a function. eg.

//ftl:verb
func Echo(ctx context.Context, in EchoRequest, tc time.TimeClient) (EchoResponse, error) {
	out, err := tc(ctx, TimeRequest{...})
}

Verb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must build the module first (with callee verb defined) in order to generate its client for use by the caller. Local verb clients are available in the generated types.ftl.go file as {VerbName}Client.

To call a verb, import the module's verb client, add it to your verb's signature, then call() it. eg.

import ftl.time.TimeClient

@Verb
fun echo(req: EchoRequest, time: TimeClient): EchoResponse {
  val response = time.call()
  // ...
}

val response = time.call()

Verb clients are generated by FTL. If the callee verb belongs to the same module as the caller, you must manually define your own client:

@VerbClient(name="time")
interface TimeClient {
    fun call(): TimeResponse
}