Quick Start
One page summary of how to start a new FTL project.
Requirements
Install the FTL CLI
Install the FTL CLI via Hermit, Homebrew, or manually.
Hermit (Mac or Linux)
FTL can be installed from the main Hermit package repository by simply:
hermit install ftl
Alternatively you can add hermit-ftl to your sources by adding the following to your Hermit environment's bin/hermit.hcl
file:
sources = ["https://github.com/block/hermit-ftl.git", "https://github.com/cashapp/hermit-packages.git"]
Homebrew (Mac or Linux)
brew tap block/ftl && brew install ftl
Manually (Mac or Linux)
Download binaries from the latest release page and place them in your $PATH
.
Install the VSCode extension
The FTL VSCode extension will run FTL within VSCode, and provide LSP support for FTL, displaying errors within the editor.
Development
Intitialize an FTL project
Once FTL is installed, initialize an FTL project:
mkdir myproject
cd myproject
ftl init myproject . --hermit
This will create an ftl-project.toml
file, a git repository, and a bin/
directory with Hermit tooling.
Create a new module
Now that you have an FTL project, create a new module:
ftl new go alice
This will place the code for the new module alice
in myproject/alice/alice.go
:
package alice
import (
"context"
"fmt"
"github.com/block/ftl/go-runtime/ftl" // Import the FTL SDK.
)
type EchoRequest struct {
Name ftl.Option[string] `json:"name"`
}
type EchoResponse struct {
Message string `json:"message"`
}
//ftl:verb
func Echo(ctx context.Context, req EchoRequest) (EchoResponse, error) {
return EchoResponse{Message: fmt.Sprintf("Hello, %s!", req.Name.Default("anonymous"))}, nil
}
Each module is its own Go module.
ftl new kotlin alice
This will create a new Maven pom.xml
based project in the directory alice
and create new example code in alice/src/main/kotlin/com/example/EchoVerb.kt
:
package com.example
import xyz.block.ftl.Export
import xyz.block.ftl.Verb
@Export
@Verb
fun echo(req: String): String = "Hello, $req!"
ftl new java alice
This will create a new Maven pom.xml
based project in the directory alice
and create new example code in alice/src/main/java/com/example/EchoVerb.java
:
package com.example;
import xyz.block.ftl.Export;
import xyz.block.ftl.Verb;
public class EchoVerb {
@Export
@Verb
public String echo(String request) {
return "Hello, " + request + "!";
}
}
Any number of modules can be added to your project, adjacent to each other.
Start the FTL cluster
VSCode
If using VSCode, opening the directory will prompt you to start FTL:
Manually
Alternatively start the local FTL development cluster from the command-line:
This will build and deploy all local modules. Modifying the code will cause ftl dev
to rebuild and redeploy the module.
Open the console
FTL has a console that allows interaction with the cluster topology, logs, traces, and more. Open a browser window at https://localhost:8899 to view it:
Call your verb
You can call verbs from the console:
Or from a terminal use ftl call
to call your verb:
Create another module
Create another module and call alice.echo
from it with by importing the alice
module and adding the verb client,
alice.EchoClient
, to the signature of the calling verb. It can be invoked as a function:
//ftl:verb
import "ftl/alice"
//ftl:verb
func Other(ctx context.Context, in Request, ec alice.EchoClient) (Response, error) {
out, err := ec(ctx, alice.EchoRequest{...})
...
}
package com.example
import xyz.block.ftl.Export
import xyz.block.ftl.Verb
import ftl.alice.EchoClient
@Export
@Verb
fun other(req: String, echo: EchoClient): String = "Hello from Other , ${echo.call(req)}!"
Note that the EchoClient
is generated by FTL and must be imported. Unfortunately at the moment JVM based languages have
a bit of a chicken-and-egg problem with the generated clients. To force a dependency between the modules you need to add
an import on a class that does not exist yet, and then FTL will generate the client for you. This will be fixed in the future.
package com.example.client;
import xyz.block.ftl.Export;
import xyz.block.ftl.Verb;
import ftl.alice.EchoClient;
public class OtherVerb {
@Export
@Verb
public String other(String request, EchoClient echoClient) {
return "Hello, " + echoClient.call(request) + "!";
}
}
Note that the EchoClient
is generated by FTL and must be imported. Unfortunately at the moment JVM based languages have
a bit of a chicken-and-egg problem with the generated clients. To force a dependency between the modules you need to add
an import on a class that does not exist yet, and then FTL will generate the client for you. This will be fixed in the future.
What next?
Explore the reference documentation.