Skip to content

Commit 5be39b7

Browse files
Javadocs and README (#462)
1 parent 391ef13 commit 5be39b7

File tree

22 files changed

+284
-102
lines changed

22 files changed

+284
-102
lines changed

README.md

Lines changed: 44 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ This SDK features:
3232

3333
### tl;dr Use project templates
3434

35-
To get started, follow the [Java quickstart](https://docs.restate.dev/get_started/quickstart).
35+
To get started, follow the [Java quickstart](https://docs.restate.dev/get_started/quickstart?sdk=java) or the [Kotlin quickstart](https://docs.restate.dev/get_started/quickstart?sdk=kotlin).
3636

3737
### Setup a project (Java)
3838

@@ -42,11 +42,15 @@ Scaffold a project using the build tool of your choice. For example, with Gradle
4242
gradle init --type java-application
4343
```
4444

45-
Add the runtime dependency [sdk-api](sdk-api) and the annotation processor dependency [sdk-api-gen](sdk-api-gen):
45+
Add the annotation processor dependency [sdk-api-gen](sdk-api-gen), and then, depending on whether you want to deploy using HTTP or Lambda, use the appropriate dependency:
4646

47-
```
48-
annotationProcessor("dev.restate:sdk-api-gen:1.2.0")
49-
implementation("dev.restate:sdk-api:1.2.0")
47+
```kotlin
48+
annotationProcessor("dev.restate:sdk-api-gen:2.0.0")
49+
50+
// For HTTP services
51+
implementation("dev.restate:sdk-java-http:2.0.0")
52+
// For Lambda services
53+
// implementation("dev.restate:sdk-java-lambda:2.0.0")
5054
```
5155

5256
### Setup a project (Kotlin)
@@ -65,11 +69,15 @@ plugins {
6569
}
6670
```
6771

68-
Add the runtime dependency [sdk-api-kotlin](sdk-api-kotlin) and the ksp dependency [sdk-api-gen](sdk-api-kotlin-gen):
72+
Add the ksp dependency [sdk-api-gen](sdk-api-kotlin-gen), and then, depending on whether you want to deploy using HTTP or Lambda, use the appropriate dependency:
6973

70-
```
71-
ksp("dev.restate:sdk-api-kotlin-gen:1.2.0")
72-
implementation("dev.restate:sdk-api-kotlin:1.2.0")
74+
```kotlin
75+
ksp("dev.restate:sdk-api-kotlin-gen:2.0.0")
76+
77+
// For HTTP services
78+
implementation("dev.restate:sdk-kotlin-http:2.0.0")
79+
// For Lambda services
80+
// implementation("dev.restate:sdk-kotlin-lambda:2.0.0")
7381
```
7482

7583
### Implement your first Restate component (Java)
@@ -80,13 +88,12 @@ Implement your first virtual object in a new class, for example:
8088
import dev.restate.sdk.ObjectContext;
8189
import dev.restate.sdk.annotation.Handler;
8290
import dev.restate.sdk.annotation.VirtualObject;
83-
import dev.restate.sdk.JsonSerdes;
8491
import dev.restate.sdk.common.StateKey;
8592

8693
@VirtualObject
8794
public class Greeter {
8895

89-
private static final StateKey<Long> COUNT = StateKey.of("total", JsonSerdes.LONG);
96+
private static final StateKey<Long> COUNT = StateKey.of("total", Long.class);
9097

9198
@Handler
9299
public String greet(ObjectContext ctx, String name) {
@@ -98,31 +105,20 @@ public class Greeter {
98105
}
99106
```
100107

101-
When using composite types/POJOs for input/output, [Jackson Databind](https://github.com/FasterXML/jackson) will be used. The Jackson dependency is not automatically included, you must add it with [`sdk-serde-jackson`](sdk-serde-jackson):
102-
103-
```
104-
implementation("dev.restate:sdk-serde-jackson:1.2.0")
105-
```
106-
107-
If you want to store types/POJOs in state, use `JacksonSerdes`:
108-
109-
```java
110-
private static final StateKey<Person> PERSON = StateKey.of("person", JacksonSerdes.of(Person.class));
111-
```
108+
By default, [Jackson Databind](https://github.com/FasterXML/jackson) will be used for serialization/deserialization. You can override this configuration by customizing the `SerdeFactory`, check out the javadocs for more details.
112109

113110
### Implement your first Restate component (Kotlin)
114111

115112
Implement your first virtual object in a new class, for example:
116113

117114
```kotlin
118-
import dev.restate.sdk.annotation.Handler
119-
import dev.restate.sdk.annotation.VirtualObject
115+
import dev.restate.sdk.annotation.*
120116
import dev.restate.sdk.kotlin.*
121117

122118
@VirtualObject
123119
class Greeter {
124120
companion object {
125-
private val COUNT = KtStateKey.json<Long>("total")
121+
private val COUNT = stateKey("total")
126122
}
127123

128124
@Handler
@@ -134,33 +130,29 @@ class Greeter {
134130
}
135131
```
136132

137-
When using composite data types for input/output, [`kotlinx.serialization`](https://github.com/Kotlin/kotlinx.serialization?tab=readme-ov-file#setup) will be used.
133+
By default [`kotlinx.serialization`](https://github.com/Kotlin/kotlinx.serialization?tab=readme-ov-file#setup) will be used for serialization/deserialization. You can override this configuration by customizing the `SerdeFactory`, check out the javadocs for more details.
138134

139135
### Deploy the service (HTTP Server)
140136

141-
To deploy the Restate service as HTTP server, add [`sdk-http-vertx`](sdk-http-vertx) to the dependencies. For example, in Gradle:
142-
143-
```
144-
implementation("dev.restate:sdk-http-vertx:1.2.0")
145-
```
146-
147-
To deploy the service, add the following code to the `main`. For example in Java:
137+
To deploy the Restate service as HTTP server, add the following code to the `main`. For example in Java:
148138

149139
```java
150140
public static void main(String[] args) {
151-
RestateHttpEndpointBuilder.builder()
152-
.bind(new Greeter())
153-
.buildAndListen();
141+
RestateHttpServer.listen(
142+
Endpoint.bind(new Greeter())
143+
);
154144
}
155145
```
156146

157147
In Kotlin:
158148

159149
```kotlin
160150
fun main() {
161-
RestateHttpEndpointBuilder.builder()
162-
.bind(Greeter())
163-
.buildAndListen()
151+
RestateHttpServer.listen(
152+
endpoint {
153+
bind(Greeter())
154+
}
155+
)
164156
}
165157
```
166158

@@ -172,13 +164,8 @@ gradle run
172164

173165
### Deploy the service (AWS Lambda)
174166

175-
To deploy the Restate service as Lambda, add [`sdk-lambda`](sdk-lambda) to the dependencies. For example, in Gradle:
176-
177-
```
178-
implementation("dev.restate:sdk-lambda:1.2.0")
179-
```
180-
181-
Configure the build tool to generate Fat-JARs, which are required by AWS Lambda to correctly load the JAR. For example, using Gradle:
167+
To deploy the Restate service as Lambda, configure the build tool to generate Fat-JARs, which are required by AWS Lambda to correctly load the JAR.
168+
For example, using Gradle:
182169

183170
```
184171
plugins {
@@ -194,7 +181,7 @@ Now create the Lambda handler invoking the service. For example, in Java:
194181
```java
195182
public class MyLambdaHandler extends BaseRestateLambdaHandler {
196183
@Override
197-
public void register(RestateLambdaEndpointBuilder builder) {
184+
public void register(Endpoint.Builder builder) {
198185
builder.bind(new Greeter());
199186
}
200187
}
@@ -204,7 +191,7 @@ In Kotlin:
204191

205192
```kotlin
206193
class MyLambdaHandler : BaseRestateLambdaHandler {
207-
override fun register(builder: RestateLambdaEndpointBuilder) {
194+
override fun register(builder: Endpoint.Builder) {
208195
builder.bind(Greeter())
209196
}
210197
}
@@ -222,13 +209,7 @@ You can now upload the generated Jar in AWS Lambda, and configure `MyLambdaHandl
222209

223210
#### Logging
224211

225-
The SDK uses log4j2 as logging facade. To enable logging, add the `log4j2` implementation to the dependencies:
226-
227-
```
228-
implementation("org.apache.logging.log4j:log4j-core:2.23.0")
229-
```
230-
231-
And configure the logging adding the file `resources/log4j2.properties`:
212+
The SDK uses log4j2 as logging facade, to configure it add the file `resources/log4j2.properties`:
232213

233214
```
234215
# Set to debug or trace if log4j initialization is failing
@@ -265,13 +246,15 @@ The SDK injects the following additional metadata to the logging context that ca
265246
* `restateInvocationId`: Invocation identifier, to be used in Restate observability tools. See https://docs.restate.dev/operate/invocation#invocation-identifier.
266247
* `restateInvocationStatus`: Invocation status, can be `WAITING_START`, `REPLAYING`, `PROCESSING`, `CLOSED`.
267248

249+
The dependencies `sdk-java-http`, `sdk-java-lambda`, `sdk-kotlin-http` and `sdk-kotlin-lambda` bring in `log4j-core` by default, but you can easily exclude/override that if you need to.
250+
268251
When assembling fat-jars, make sure to enable merging META-INF/services files. For more info, see https://github.com/apache/logging-log4j2/issues/2099.
269252

270253
#### Tracing with OpenTelemetry
271254

272-
The SDK can generate additional tracing information on top of what Restate already publishes. See https://docs.restate.dev/operate/monitoring/tracing to configure Restate tracing.
255+
The SDK automatically propagates the OpenTelemetry `Context` from the `restate-server` into your handler. You can use that to create custom spans.
273256

274-
You can the additional SDK tracing information by configuring the `OpenTelemetry` in the `RestateHttpEndpointBuilder`/`LambdaRestateServer`.
257+
To configure the `OpenTelemetry` that should be used by the SDK to publish traces, configure it in the `Endpoint.Builder` object.
275258

276259
For example, to set up tracing using environment variables, add the following modules to your dependencies:
277260

@@ -280,7 +263,7 @@ implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.38.
280263
implementation("io.opentelemetry:opentelemetry-exporter-otlp:1.38.0")
281264
```
282265

283-
And then configure it in the Restate builder:
266+
And then configure it in the endpoint builder:
284267

285268
```java
286269
.withOpenTelemetry(AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk())
@@ -294,7 +277,9 @@ export OTEL_TRACES_SAMPLER=always_on
294277
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:14250
295278
```
296279

297-
Please refer to the [Opentelemetry manual instrumentation documentation](https://opentelemetry.io/docs/instrumentation/java/manual/#manual-instrumentation-setup) and the [autoconfigure documentation](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md) for more info.
280+
Please refer to the [Opentelemetry manual instrumentation documentation](https://opentelemetry.io/docs/instrumentation/java/manual/#manual-instrumentation-setup) and the [autoconfigure documentation](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md) for more info.
281+
282+
See https://docs.restate.dev/operate/monitoring/tracing to configure Restate tracing.
298283

299284
## Versions
300285

@@ -338,9 +323,3 @@ To publish local snapshots of the project:
338323
```shell
339324
./gradlew -DskipSigning publishToMavenLocal
340325
```
341-
342-
To update the [`service-protocol`](https://github.com/restatedev/service-protocol/) git subtree:
343-
344-
```shell
345-
git subtree pull --prefix sdk-core/src/main/service-protocol/ git@github.com:restatedev/service-protocol.git main --squash
346-
```

common/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ dependencies {
1313
testImplementation(libs.junit.jupiter)
1414
testImplementation(libs.assertj)
1515
}
16+
17+
tasks.withType<Javadoc> { isFailOnError = false }

common/src/main/java/dev/restate/common/Request.java

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
import java.util.Objects;
1717
import org.jspecify.annotations.Nullable;
1818

19+
/**
20+
* Object encapsulating request parameters.
21+
*
22+
* @param <Req> the request type
23+
* @param <Res> the response type
24+
*/
1925
public sealed class Request<Req, Res> permits SendRequest {
2026

2127
private final Target target;
@@ -67,21 +73,25 @@ public Map<String, String> headers() {
6773
return headers;
6874
}
6975

76+
/**
77+
* Create a new {@link Builder} for the given {@link Target}, request and response {@link TypeTag}
78+
* and {@code request} object.
79+
*
80+
* <p>When using the annotation processor, you can rely on the generated {@code Client} class or
81+
* the generated {@code Requests} class, instead of manually using this builder.
82+
*/
7083
public static <Req, Res> Builder<Req, Res> of(
7184
Target target, TypeTag<Req> reqTypeTag, TypeTag<Res> resTypeTag, Req request) {
7285
return new Builder<>(target, reqTypeTag, resTypeTag, request);
7386
}
7487

75-
public static <Req> Builder<Req, Void> withNoResponseBody(
76-
Target target, TypeTag<Req> reqTypeTag, Req request) {
77-
return new Builder<>(target, reqTypeTag, Serde.VOID, request);
78-
}
79-
80-
public static <Res> Builder<Void, Res> withNoRequestBody(Target target, TypeTag<Res> resTypeTag) {
81-
return new Builder<>(target, Serde.VOID, resTypeTag, null);
82-
}
83-
84-
public static Builder<byte[], byte[]> ofRaw(Target target, byte[] request) {
88+
/**
89+
* Create a new {@link Builder} for the given {@link Target} and {@code request} byte array.
90+
*
91+
* <p>When using the annotation processor, you can rely on the generated {@code Client} class or
92+
* the generated {@code Requests} class, instead of manually using this builder.
93+
*/
94+
public static Builder<byte[], byte[]> of(Target target, byte[] request) {
8595
return new Builder<>(target, TypeTag.of(Serde.RAW), TypeTag.of(Serde.RAW), request);
8696
}
8797

@@ -153,6 +163,9 @@ public Builder<Req, Res> headers(Map<String, String> newHeaders) {
153163
return idempotencyKey;
154164
}
155165

166+
/**
167+
* @param idempotencyKey Idempotency key to attach in the request.
168+
*/
156169
public Builder<Req, Res> setIdempotencyKey(@Nullable String idempotencyKey) {
157170
return idempotencyKey(idempotencyKey);
158171
}
@@ -161,20 +174,32 @@ public Builder<Req, Res> setIdempotencyKey(@Nullable String idempotencyKey) {
161174
return headers;
162175
}
163176

177+
/**
178+
* @param headers headers to send together with the request.
179+
*/
164180
public Builder<Req, Res> setHeaders(@Nullable Map<String, String> headers) {
165181
return headers(headers);
166182
}
167183

184+
/**
185+
* @return build the request as send request.
186+
*/
168187
public SendRequest<Req, Res> asSend() {
169188
return new SendRequest<>(
170189
target, reqTypeTag, resTypeTag, request, idempotencyKey, headers, null);
171190
}
172191

192+
/**
193+
* @return build the request as send request delayed by the given {@code delay}.
194+
*/
173195
public SendRequest<Req, Res> asSendDelayed(Duration delay) {
174196
return new SendRequest<>(
175197
target, reqTypeTag, resTypeTag, request, idempotencyKey, headers, delay);
176198
}
177199

200+
/**
201+
* @return build the request as send request.
202+
*/
178203
public Request<Req, Res> build() {
179204
return new Request<>(
180205
this.target,
@@ -196,11 +221,17 @@ public Builder<Req, Res> toBuilder() {
196221
this.headers);
197222
}
198223

224+
/**
225+
* @return copy this request as send.
226+
*/
199227
public SendRequest<Req, Res> asSend() {
200228
return new SendRequest<>(
201229
target, reqTypeTag, resTypeTag, request, idempotencyKey, headers, null);
202230
}
203231

232+
/**
233+
* @return copy this request as send request delayed by the given {@code delay}.
234+
*/
204235
public SendRequest<Req, Res> asSendDelayed(Duration delay) {
205236
return new SendRequest<>(
206237
target, reqTypeTag, resTypeTag, request, idempotencyKey, headers, delay);

common/src/main/java/dev/restate/common/SendRequest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
import java.util.Objects;
1515
import org.jspecify.annotations.Nullable;
1616

17+
/**
18+
* Object encapsulating request parameters, including the parameters exclusive to one way calls
19+
* (also referred as send).
20+
*
21+
* @param <Req> the request type
22+
* @param <Res> the response type
23+
*/
1724
public final class SendRequest<Req, Res> extends Request<Req, Res> {
1825

1926
@Nullable private final Duration delay;

common/src/main/java/dev/restate/common/Slice.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.nio.ByteBuffer;
1212
import java.nio.charset.StandardCharsets;
1313

14+
/** Wrapper type for byte slices. */
1415
public interface Slice {
1516

1617
int readableBytes();
@@ -27,6 +28,7 @@ public interface Slice {
2728

2829
byte[] toByteArray();
2930

31+
/** Wrap a {@link ByteBuffer}. This will not copy the buffer. */
3032
static Slice wrap(ByteBuffer byteBuffer) {
3133
return new Slice() {
3234
@Override

0 commit comments

Comments
 (0)