diff --git a/docs/content/docs/reference/cron.md b/docs/content/docs/reference/cron.md index 962b9ca44..8489c5970 100644 --- a/docs/content/docs/reference/cron.md +++ b/docs/content/docs/reference/cron.md @@ -32,6 +32,7 @@ func Hourly(ctx context.Context) error { ```kotlin import xyz.block.ftl.Cron + @Cron("0 * * * *") fun hourly() { @@ -63,6 +64,7 @@ func TwiceADay(ctx context.Context) error { ```kotlin import xyz.block.ftl.Cron + @Cron("12h") fun twiceADay() { @@ -94,6 +96,7 @@ func Mondays(ctx context.Context) error { ```kotlin import xyz.block.ftl.Cron + @Cron("Mon") fun mondays() { @@ -104,6 +107,7 @@ fun mondays() { import xyz.block.ftl.Cron; class MyCron { + @Cron("Mon") void mondays() { diff --git a/docs/content/docs/reference/ingress.md b/docs/content/docs/reference/ingress.md index 1c1bf24e1..d6bdbfc86 100644 --- a/docs/content/docs/reference/ingress.md +++ b/docs/content/docs/reference/ingress.md @@ -169,49 +169,37 @@ curl -i http://localhost:8891/users/123/posts/456?@json=%7B%22tag%22%3A%22ftl%22 ``` -Kotlin uses the `@Ingress` annotation to define HTTP endpoints. These endpoints will be exposed on the default ingress port (local development defaults to `http://localhost:8891`). + +Kotlin Languages use the `JAX-RS` annotations to define HTTP endpoints. The following example shows how to define an HTTP endpoint in Kotlin. 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. ```kotlin -import xyz.block.ftl.Ingress -import xyz.block.ftl.Option - -// Simple GET endpoint with path and query parameters -@Ingress("GET /users/{userId}/posts") -fun getPost(request: Request): Response { - val userId = request.pathParams["userId"] - val postId = request.queryParams["postId"] - return Response.ok(Post(userId, postId)) -} -// POST endpoint with request body -@Ingress("POST /users/{userId}/posts") -fun createPost(request: Request): Response { - val userId = request.pathParams["userId"] - val body = request.body() - return Response.created(Post(userId, body.title)) -} +import java.util.List -// Request body data class -data class PostBody( - val title: String, - val content: String, - val tag: Option // Optional field using Option type -) - -// Response data class -data class Post( - val userId: String, - val title: String -) -``` +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 { -Key features: -- The `@Ingress` annotation takes a string parameter combining the HTTP method and path -- Path parameters are accessed via `request.pathParams` -- Query parameters are accessed via `request.queryParams` -- Request bodies can be automatically deserialized using `request.body()` -- Optional fields are represented using the `Option` type -- Response helpers like `Response.ok()` and `Response.created()` for common status codes + @GET + @Path("/http/users/{userId}/posts") + fun get(@RestPath userId: String,@QueryParam("postId") post: String) : String { + //... + } + +} +``` +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. diff --git a/docs/content/docs/reference/verbs.md b/docs/content/docs/reference/verbs.md index 01d8b1dcf..b40d7f433 100644 --- a/docs/content/docs/reference/verbs.md +++ b/docs/content/docs/reference/verbs.md @@ -69,13 +69,17 @@ public Output f(Input input) { } eg. ```java -public class EchoRequest {} +import xyz.block.ftl.Verb; -public class EchoResponse {} +class EchoRequest {} -@Verb -public EchoResponse echo(EchoRequest request) { - // ... +class EchoResponse {} + +public class EchoClass { + @Verb + public EchoResponse echo(EchoRequest request) { + // ... + } } ``` @@ -106,6 +110,7 @@ To call a verb, import the module's verb client, add it to your verb's signature ```kotlin import ftl.time.TimeClient +import xyz.block.ftl.Verb @Verb fun echo(req: EchoRequest, time: TimeClient): EchoResponse { @@ -130,11 +135,14 @@ To call a verb, import the module's verb client, add it to your verb's signature ```java import ftl.time.TimeClient; - -@Verb -public EchoResponse echo(EchoRequest request, TimeClient time) { - TimeResponse response = time.call(); - // ... +import xyz.block.ftl.Verb; + +public class EchoClass { + @Verb + public EchoResponse echo(EchoRequest request, TimeClient time) { + TimeResponse response = time.call(); + // ... + } } ```