Skip to content

Commit

Permalink
chore: update docs to include more JVM examples (#2922)
Browse files Browse the repository at this point in the history
This is still a work in progress, but this improves the situation a lot.
  • Loading branch information
stuartwdouglas authored Oct 1, 2024
1 parent a26bcf9 commit c240d36
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 33 deletions.
87 changes: 86 additions & 1 deletion docs/content/docs/getting-started/quick-start/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ This will create an `ftl-project.toml` file, a git repository, and a `bin/` dire

Now that you have an FTL project, create a new module:

{% code_selector() %}

<!-- go -->
```
ftl new go . alice
```

This will place the code for the new module `alice` in `myproject/alice/alice.go`:

```go
Expand Down Expand Up @@ -98,6 +100,48 @@ func Echo(ctx context.Context, req EchoRequest) (EchoResponse, error) {

Each module is its own Go module.

<!-- kotlin -->
```
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`:

```kotlin
package com.example

import xyz.block.ftl.Export
import xyz.block.ftl.Verb


@Export
@Verb
fun echo(req: String): String = "Hello, $req!"
```
<!-- java -->
```
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`:

```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 + "!";
}
}
```
{% end %}


Any number of modules can be added to your project, adjacent to each other.

### Start the FTL cluster
Expand Down Expand Up @@ -139,6 +183,9 @@ Or from a terminal use `ftl call` to call your verb:
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:

{% code_selector() %}

<!-- go -->
```go
//ftl:verb
import "ftl/alice"
Expand All @@ -149,6 +196,44 @@ func Other(ctx context.Context, in Request, ec alice.EchoClient) (Response, erro
...
}
```
<!-- kotlin -->
```kotlin
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.
<!-- java -->
```java
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.
<!-- java -->
{% end %}

### What next?

Expand Down
66 changes: 66 additions & 0 deletions docs/content/docs/reference/cron.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,93 @@ You can also use a shorthand syntax for the cron job, supporting seconds (`s`),

The following function will be called hourly:

{% code_selector() %}
<!-- go -->
```go
//ftl:cron 0 * * * *
func Hourly(ctx context.Context) error {
// ...
}
```
<!-- kotlin -->
```kotlin
import xyz.block.ftl.Cron
@Cron("0 * * * *")
fun hourly() {

}
```
<!-- java -->
```java
import xyz.block.ftl.Cron;

class MyCron {
@Cron("0 * * * *")
void hourly() {

}
}
```

{% end %}
Every 12 hours, starting at UTC midnight:

{% code_selector() %}
<!-- go -->
```go
//ftl:cron 12h
func TwiceADay(ctx context.Context) error {
// ...
}
```
<!-- kotlin -->
```kotlin
import xyz.block.ftl.Cron
@Cron("12h")
fun twiceADay() {

}
```
<!-- java -->
```java
import xyz.block.ftl.Cron;

class MyCron {
@Cron("12h")
void twiceADay() {

}
}
```
{% end %}

Every Monday at UTC midnight:

{% code_selector() %}
<!-- go -->
```go
//ftl:cron Mon
func Mondays(ctx context.Context) error {
// ...
}
```
<!-- kotlin -->
```kotlin
import xyz.block.ftl.Cron
@Cron("Mon")
fun mondays() {

}
```
<!-- java -->
```java
import xyz.block.ftl.Cron;

class MyCron {
@Cron("Mon")
void mondays() {

}
}
```
{% end %}
40 changes: 40 additions & 0 deletions docs/content/docs/reference/ingress.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Verbs annotated with `ftl:ingress` will be exposed via HTTP (`http` is the defau

The following will be available at `http://localhost:8891/http/users/123/posts?postId=456`.

{% code_selector() %}
<!-- go -->

```go
type GetRequestPathParams struct {
UserID string `json:"userId"`
Expand Down Expand Up @@ -164,3 +167,40 @@ Complex query params can also be encoded as JSON using the `@json` query paramet
```bash
curl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22%7D
```


<!-- java -->

JVM Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Java. As the underling implementation is based on [Quarkus](https://quarkus.io)
it is also possible to use the [Quarkus extensions to the JAX-RS annotations](https://quarkus.io/guides/rest#accessing-request-parameters):

In general the difference between the Quarkus annotation and the standard JAX-RS ones is that the Quarkus parameters infer the parameter name from the method parameter name, while the JAX-RS ones require the parameter name to be explicitly defined.

```java

import java.util.List;

import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;

import jakarta.ws.rs.QueryParam; // JAX-RS annotation to get the query parameter
import org.jboss.resteasy.reactive.RestPath; // Quarkus annotation to get the path parameter

@Path("/")
public class TestHTTP {

@GET
@Path("/http/users/{userId}/posts")
public String get(@RestPath String userId, @QueryParam("postId") String post) {
//...
}

}
```
Under the hood these HTTP invocations are being mapped to verbs that take a `builtin.HttpRequest` and return a `builtin.HttpResponse`. This is not exposed directly to the user, but is instead mapped directly to `JAX-RS` annotations.

{% end %}

50 changes: 43 additions & 7 deletions docs/content/docs/reference/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,58 @@ top = false

{% code_selector() %}

Some aspects of FTL rely on a runtime which must be imported with:

<!-- go -->

Some aspects of FTL rely on a runtime which must be imported with:

```go
import "github.com/TBD54566975/ftl/go-runtime/ftl"
```

<!-- kotlin -->

```kotlin
// Declare a verb you want to use:
import xyz.block.ftl.Verb
The easiest way to get started with Kotlin is to use the `ftl-build-parent-kotlin` parent POM. This will automatically include the FTL runtime as a dependency, and setup all required plugins:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>xyz.block.ftl</groupId>
<artifactId>ftl-build-parent-kotlin</artifactId>
<version>${ftl.version}</version>
</parent>

</project>
```

If you do not want to use a parent pom then you can copy the plugins and dependencies from the parent pom into your own pom.

<!-- java -->

The easiest way to get started with Java is to use the `ftl-build-parent-java` parent POM. This will automatically include the FTL runtime as a dependency, and setup all required plugins:

// When using the export feature:
import xyz.block.ftl.Export
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>xyz.block.ftl</groupId>
<artifactId>ftl-build-parent-java</artifactId>
<version>${ftl.version}</version>
</parent>

</project>
```

If you do not want to use a parent pom then you can copy the plugins and dependencies from the parent pom into your own pom.

{% end %}
24 changes: 23 additions & 1 deletion docs/content/docs/reference/visibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Exporting a declaration makes it accessible to other modules. Some declarations

Types that are transitively referenced by an exported declaration will be automatically exported unless they were already defined but unexported. In this case, an error will be raised and the type must be explicitly exported.

The following table describes the directives used to export the corresponding declaration:
The following table describes the go directives used to export the corresponding declaration:

| Symbol | Export syntax |
| ------------- | ------------------------ |
Expand All @@ -31,14 +31,36 @@ The following table describes the directives used to export the corresponding de
| Typealias | `//ftl:typealias export` |
| Topic | `//ftl:export` [^1] |

For JVM languages the `@Export` annotation can be used to export a declaration.

eg.

{% code_selector() %}

<!-- go -->
```go
//ftl:verb export
func Verb(ctx context.Context, in In) (Out, error)

//ftl:typealias export
type UserID string
```
<!-- kotlin -->
```kotlin
@Verb
@Export
fun time(): TimeResponse {
// ...
}
```
<!-- java -->
```java
@Verb
@Export
TimeResponse time() {
// ...
}
```
{% end %}

[^1]: By default, topics do not require any annotations as the declaration itself is sufficient.
Loading

0 comments on commit c240d36

Please sign in to comment.